home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / machserver / 1.098 / mach / ds5000.md / machUNIXSyscall.c < prev    next >
C/C++ Source or Header  |  1991-08-09  |  84KB  |  2,809 lines

  1. /* 
  2.  * machUNIXSyscall.c --
  3.  *
  4.  *      UNIX system call handlers.  I'm sorry about the lack of header
  5.  *    comments but I didn't feel like putting 100 headers that only
  6.  *    said "MachUNIXFooBar -- emulates the FooBar system call".  Of course
  7.  *    this should be done to match the Sprite coding conventions.
  8.  *
  9.  *    The routines in this file and the other associated files in this
  10.  *    directory (socket.c, ioctl.c, etc.) provide full binary compatible
  11.  *    with the following exceptions:
  12.  *
  13.  *        1) System call handlers are called with a Sprite context
  14.  *           rather than a UNIX context.  This could be fixed by
  15.  *           setting a compatibility bit in the machine state struct
  16.  *           when the first UNIX system call happens and then emulating
  17.  *           UNIX signal handler calling conventions after that for
  18.  *           the process.
  19.  *
  20.  *        2) Sprite doesn't implement ptys so we can't run commands
  21.  *           like xterm directly.
  22.  *
  23.  *        3) Reads that are interrupted do not restart like they
  24.  *           do in Sprite.  The problem is that if we restart them
  25.  *           in here then the user never has the oppurtunity to 
  26.  *           handle the signal.  A possible solution is to return to
  27.  *           user mode and then when the signal handler returns restart
  28.  *           the system call.  This will be complicated because the
  29.  *           arguments have to be kept around somehow.
  30.  *
  31.  *    IMPLEMENTATION DETAILS
  32.  *
  33.  *    The only real interesting thing about this implementation is that
  34.  *    it's a little tricky calling kernel system call stubs from inside
  35.  *    the kernel.  The problem is that the stubs assume that all pointers
  36.  *    point into user space.  However, when we are emulating a system
  37.  *    call we may call a system call stub (e.g. Fs_OpenStub) and want to
  38.  *    pass a pointer to a kernel structure.  An example of this is 
  39.  *    MachUNIXOpen (emulation of open) which calls Fs_OpenStub.  Fs_OpenStub
  40.  *    returns the streamid in an out parameter in the user's address space
  41.  *    but open doesn't provide any place to put it. The solution that I used
  42.  *    was to push things onto the users stack and then copy the result
  43.  *    back into the kernel's address space.  What, you don't understand
  44.  *    what the hell I'm talking about?  Well look at MachUNIXOpen for
  45.  *    an example.
  46.  *    
  47.  *    If something in here looks bizarre and I forgot to comment it it's
  48.  *    probably because the UNIX system call stub does something weird.
  49.  *    Extract it from the UNIX C library and disassemble it and things
  50.  *    will probably make more sense.
  51.  *    
  52.  *    Copyright (C) 1989 Digital Equipment Corporation.
  53.  *    Permission to use, copy, modify, and distribute this software and
  54.  *    its documentation for any purpose and without fee is hereby granted,
  55.  *    provided that the above copyright notice appears in all copies.  
  56.  *    Digital Equipment Corporation makes no representations about the
  57.  *    suitability of this software for any purpose.  It is provided "as is"
  58.  *    without express or implied warranty.
  59.  */
  60.  
  61. #ifndef lint
  62. static char rcsid[] = "$Header: /sprite/src/kernel/mach/ds3100.md/RCS/machUNIXSyscall.c,v 9.13 91/08/09 15:19:51 shirriff Exp $ SPRITE (DECWRL)";
  63. #endif not lint
  64.  
  65. #include "sprite.h"
  66. #include "status.h"
  67. #include "machConst.h"
  68. #include "machInt.h"
  69. #include "mach.h"
  70. #include "proc.h"
  71. #include "vm.h"
  72. #include "user/sys/types.h"
  73. #include "user/sys/file.h"
  74. #include "user/fs.h"
  75. #include "user/sys/wait.h"
  76. #include "user/sys/time.h"
  77. #include "user/sys/resource.h"
  78. #include "user/sys/uio.h"
  79. #include "stat.h"
  80. #include "ultrixSignal.h"
  81. #include "sys.h"
  82. #include "fs.h"
  83. #include "fsdm.h"
  84. #include "fslcl.h"    /* Directory format */
  85. #include "sys/types.h"
  86.  
  87. /*
  88.  * System call entry structure.  Note that this is different than the one
  89.  * in the sys directory.  This should be converted over to that format
  90.  * with the addition of the name field.
  91.  */
  92. typedef struct {
  93.     char        *name;
  94.     int            numArgs;
  95.     ReturnStatus    (*func)();
  96. } SyscallInfo;
  97.  
  98. extern int machNewUnixCompat;
  99.  
  100. /*
  101.  * Values for system call tracing:
  102.  *
  103.  *    0:     Use the fast assembly language interface and don't trace 
  104.  *        anything.
  105.  *    1:     Use the slower C interface but no trace printing.
  106.  *    > 1:     Use the slower C interface and trace system calls.
  107.  */
  108.  
  109. /*
  110.  * The code to disable migration for processes using the compatibility
  111.  * library is in the slower C interface...
  112.  */
  113. #ifdef CANT_MIGRATE_COMPAT
  114. int machUNIXSyscallTrace = 0;
  115. #else /* CANT_MIGRATE_COMPAT */
  116. int machUNIXSyscallTrace = 0;
  117. #endif /* CANT_MIGRATE_COMPAT */
  118.  
  119. /*
  120.  * Zillions of forward declarations.
  121.  */
  122. extern int MachUNIXIoctl _ARGS_((int fd, int request, char *buf));
  123. extern int MachUNIXFcntl _ARGS_((int fd, int cmd, int arg));
  124. extern Boolean MachUNIXSyscall _ARGS_((void));
  125. extern ReturnStatus MachUNIXExit _ARGS_((int status));
  126. extern ReturnStatus MachUNIXFork _ARGS_((void));
  127. extern ReturnStatus MachUNIXVFork _ARGS_((void));
  128. extern ReturnStatus MachUNIXRead _ARGS_((int streamID, char *buffer, int numBytes));
  129. extern ReturnStatus MachUNIXWrite _ARGS_((int streamID, char *buffer, int numBytes));
  130. extern ReturnStatus MachUNIXOpen _ARGS_((char *pathName, int unixFlags, int permissions));
  131. extern ReturnStatus MachUNIXClose _ARGS_((int streamID));
  132. extern ReturnStatus MachUNIXCreat _ARGS_((char *pathName, int permissions));
  133. extern ReturnStatus MachUNIXLink _ARGS_((char *name1, char *name2));
  134. extern ReturnStatus MachUNIXUnlink _ARGS_((char *pathName));
  135. extern ReturnStatus MachUNIXExecve _ARGS_((char *name, char *argv[], char *envp[]));
  136. extern ReturnStatus MachUNIXExecv _ARGS_((char *name, char **argv));
  137. extern ReturnStatus MachUNIXChdir _ARGS_((char *pathName));
  138. extern ReturnStatus MachUNIXChmod _ARGS_((char *path, int mode));
  139. extern ReturnStatus MachUNIXFChmod _ARGS_((int fd, int mode));
  140. extern ReturnStatus MachUNIXChown _ARGS_((char *path, int owner, int group));
  141. extern ReturnStatus MachUNIXFChown _ARGS_((int fd, int owner, int group));
  142. extern ReturnStatus MachUNIXSbrk _ARGS_((Address addr));
  143. extern ReturnStatus MachUNIXLseek _ARGS_((int streamID, long offset, int whence));
  144. extern ReturnStatus MachUNIXGetPID _ARGS_((void));
  145. extern ReturnStatus MachUNIXGetuid _ARGS_((void));
  146. extern ReturnStatus MachUNIXAccess _ARGS_((char *pathName, int mode));
  147. extern ReturnStatus MachUNIXKill _ARGS_((int pid, int sig));
  148. extern ReturnStatus MachUNIXStat _ARGS_((char *pathName, struct stat *attsBufPtr));
  149. extern ReturnStatus MachUNIXLstat _ARGS_((char *pathName, struct stat *attsBufPtr));
  150. extern ReturnStatus MachUNIXFstat _ARGS_((int fd, struct stat *attsBufPtr));
  151. extern ReturnStatus MachUNIXDup _ARGS_((int oldStreamID));
  152. extern ReturnStatus MachUNIXDup2 _ARGS_((int oldStreamID, int newStreamID));
  153. extern ReturnStatus MachUNIXPipe _ARGS_((int filedes[2]));
  154. extern ReturnStatus MachUNIXGetGID _ARGS_((void));
  155. extern ReturnStatus MachUNIXSymlink _ARGS_((char *target, char *link));
  156. extern ReturnStatus MachUNIXReadLink _ARGS_((char *link, char *buffer, int numBytes));
  157. extern ReturnStatus MachUNIXUmask _ARGS_((int newMask));
  158. extern ReturnStatus MachUNIXGetPageSize _ARGS_((void));
  159. extern ReturnStatus MachUNIXGetGroups _ARGS_((int gidsetlen, int *gidset));
  160. extern ReturnStatus MachUNIXSetGroups _ARGS_((int ngroups, int *gidset));
  161. extern ReturnStatus MachUNIXGetPGrp _ARGS_((int pid));
  162. extern ReturnStatus MachUNIXSetPGrp _ARGS_((int pid, int pgrp));
  163. extern ReturnStatus MachUNIXWait _ARGS_((union wait *statusPtr, int options, struct rusage *unixRusagePtr));
  164. extern ReturnStatus MachUNIXGetDTableSize _ARGS_((void));
  165. extern ReturnStatus MachUNIXSelect _ARGS_((int width, int *readfds, int *writefds, int *exceptfds, Time *timeout));
  166. extern ReturnStatus MachUNIXFSync _ARGS_((int fd));
  167. extern ReturnStatus MachUNIXSetPriority _ARGS_((int which, int who, int prio));
  168. extern ReturnStatus MachUNIXGetPriority _ARGS_((int which, int who, int prio));
  169. extern ReturnStatus MachUNIXGetTimeOfDay _ARGS_((struct timeval *tp, struct timezone *tzpPtr));
  170. extern ReturnStatus MachUNIXSetTimeOfDay _ARGS_((struct timeval *tp, struct timezone *tzpPtr));
  171. extern ReturnStatus MachUNIXGetDirEntries _ARGS_((int fd, char *buf, int nbytes, long *basep));
  172. extern ReturnStatus MachUNIXGetRUsage _ARGS_((int who, struct rusage *rusage));
  173. extern ReturnStatus MachUNIXReadv _ARGS_((int stream, register struct iovec *iov, int iovcnt));
  174. extern ReturnStatus MachUNIXWritev _ARGS_((int stream, register struct iovec *iov, int iovcnt));
  175. extern ReturnStatus MachUNIXSetREUID _ARGS_((int ruid, int euid));
  176. extern ReturnStatus MachUNIXSetREGID _ARGS_((int rgid, int egid));
  177. extern ReturnStatus MachUNIXRename _ARGS_((char *from, char *to));
  178. extern ReturnStatus MachUNIXTruncate _ARGS_((char *path, unsigned long length));
  179. extern ReturnStatus MachUNIXFTruncate _ARGS_((int fd, unsigned long length));
  180. extern ReturnStatus MachUNIXLongJumpReturn _ARGS_((struct sigcontext *sigContextPtr));
  181. extern ReturnStatus MachUNIXFLock _ARGS_((int descriptor, int operation));
  182. extern ReturnStatus MachUNIXMkDir _ARGS_((char *pathName, int permissions));
  183. extern ReturnStatus MachUNIXRMDir _ARGS_((char *pathName));
  184. extern ReturnStatus MachUNIXUTimes _ARGS_((char *path, struct timeval tvp[2]));
  185. extern ReturnStatus MachUNIXKillPG _ARGS_((int pgrp, int sig));
  186. extern ReturnStatus MachUNIXGetRLimit _ARGS_((void));
  187. extern ReturnStatus MachUNIXSetRLimit _ARGS_((void));
  188. extern ReturnStatus MachUNIXGetHostName _ARGS_((char *name, int namelen));
  189. extern ReturnStatus MachUNIXSetHostName _ARGS_((char *name, int namelen));
  190. extern ReturnStatus MachUNIXGetHostID _ARGS_((void));
  191. extern ReturnStatus MachUNIXSetHostID _ARGS_((int hostid));
  192. extern ReturnStatus MachUNIXGetDomainName _ARGS_((char *name, int namelen));
  193. extern ReturnStatus MachUNIXSetDomainName _ARGS_((char *name, int namelen));
  194. extern ReturnStatus MachUNIXGetItimer _ARGS_((int which, struct itimerval *value));
  195. extern ReturnStatus MachUNIXSetITimer _ARGS_((int which, struct itimerval *value, struct itimerval *ovalue));
  196. extern ReturnStatus MachUNIXGetSysInfo _ARGS_((unsigned op, char *buffer, unsigned nbytes, int *start, char *arg));
  197. extern ReturnStatus MachUNIXSemctl _ARGS_((int semid, int semnum, int cmd, unionsemun arg));
  198. extern ReturnStatus MachUNIXSemop _ARGS_((int semid, struct sembuf *sops, int nsops));
  199. extern ReturnStatus MachUNIXSemget _ARGS_((key_t key, int nsems, int semflg));
  200. extern ReturnStatus MachUNIXMmap _ARGS_((caddr_t addr, int len, int prot, int share, int fd, off_t pos));
  201. extern ReturnStatus MachUNIXMunmap _ARGS_((caddr_t addr, int len));
  202. extern ReturnStatus MachUNIXMincore _ARGS_((caddr_t addr, int len, char vec[]));
  203. extern ReturnStatus MachUNIXSocketPair _ARGS_((int d, int type, int protocol, int sv[2]));
  204. extern ReturnStatus MachUNIXReboot _ARGS_((int howto));
  205. extern ReturnStatus MachUNIXSync _ARGS_((void));
  206. extern ReturnStatus MachUNIXPtrace _ARGS_((int request, int pid, int *addr, int data));
  207. extern ReturnStatus MachUNIXGetDOpt _ARGS_((void));
  208. extern ReturnStatus MachUNIXSetDOpt _ARGS_((void));
  209. extern ReturnStatus MachUNIXAdjTime _ARGS_((struct timeval *delta, struct timeval *olddelta));
  210. extern ReturnStatus MachUNIXError _ARGS_((void));
  211. extern ReturnStatus MachUNIXProfil _ARGS_((char *buffer, int bufsize, int offset, int scale));
  212. extern ReturnStatus MachUNIXSigvec _ARGS_((int sig, struct sigvec *newVectorPtr, struct sigvec *oldVectorPtr));
  213. extern ReturnStatus MachUNIXBlock _ARGS_((int mask));
  214. extern ReturnStatus MachUNIXSigSetmask _ARGS_((int mask));
  215. extern ReturnStatus MachUNIXSigPause _ARGS_((int mask));
  216. extern ReturnStatus MachUNIXSigStack _ARGS_((struct sigstack *ss, struct sigstack *oss));
  217. extern ReturnStatus MachUNIXAccept _ARGS_((int socketID, struct sockaddr_in *addrPtr, int *addrLenPtr));
  218. extern ReturnStatus MachUNIXBind _ARGS_((int socketID, struct sockaddr *namePtr, int nameLen));
  219. extern ReturnStatus MachUNIXConnect _ARGS_((int socketID, struct sockaddr *namePtr, int nameLen));
  220. extern ReturnStatus MachUNIXGetPeerName _ARGS_((int socketID, struct sockaddr *namePtr, int *nameLenPtr));
  221. extern ReturnStatus MachUNIXGetSockName _ARGS_((int socketID, struct sockaddr *namePtr, int *nameLenPtr));
  222. extern ReturnStatus MachUNIXGetSockOpt _ARGS_((int socketID, int level, int optName, char *optVal, int *optLenPtr));
  223. extern ReturnStatus MachUNIXSetSockOpt _ARGS_((int socketID, int level, int optName, char *optVal, int optLen));
  224. extern ReturnStatus MachUNIXListen _ARGS_((int socketID, int backlog));
  225. extern ReturnStatus MachUNIXRecv _ARGS_((int socketID, char *bufPtr, int bufSize, int flags));
  226. extern ReturnStatus MachUNIXRecvFrom _ARGS_((int socketID, char *bufPtr, int bufSize, int flags, struct sockaddr *senderPtr, int *senderLenPtr));
  227. extern ReturnStatus MachUNIXRecvMsg _ARGS_((int socketID, struct msghdr *msgPtr, int flags));
  228. extern ReturnStatus MachUNIXSend _ARGS_((int socketID, char *bufPtr, int bufSize, int flags));
  229. extern ReturnStatus MachUNIXSendTo _ARGS_((int socketID, char *bufPtr, int bufSize, int flags, struct sockaddr *destPtr, int destLen));
  230. extern ReturnStatus MachUNIXSendMsg _ARGS_((int socketID, struct msghdr *msgPtr, int flags));
  231. extern ReturnStatus MachUNIXSocket _ARGS_((int domain, int type, int protocol));
  232. extern ReturnStatus MachUNIXShutdown _ARGS_((int socketID, int action));
  233.  
  234.  
  235. /*
  236.  * The system call table.
  237.  */
  238. SyscallInfo machUNIXSysCallTable[] = {
  239. #if 1
  240.     "indir",         -1,     MachUNIXError,
  241.     "exit",            -1,     MachUNIXExit,
  242.     "fork",            -1,     MachUNIXFork,
  243.     "read",            -1,     MachUNIXRead,
  244.     "write",         -1,     MachUNIXWrite,
  245.     "open",            -1,     MachUNIXOpen,
  246.     "close",         -1,     MachUNIXClose,
  247.     "old wait",         -1,     MachUNIXError,
  248.     "creat",         -1,     MachUNIXCreat,
  249.     "link",            -1,     MachUNIXLink,    
  250.     "unlink",         -1,     MachUNIXUnlink,
  251.     "execv",         -1,     MachUNIXExecv,
  252.     "chdir",         -1,     MachUNIXChdir,
  253.     "old time",         -1,     MachUNIXError,
  254.     "mknod",         -1,     MachUNIXError,
  255.     "chmod",         -1,     MachUNIXChmod,
  256.     "chown",         -1,     MachUNIXChown, 
  257.     "sbrk",         -1,     MachUNIXSbrk,
  258.     "old stat",         -1,    MachUNIXError,
  259.     "lseek",         -1,     MachUNIXLseek,
  260.     "getpid",         -1,     MachUNIXGetPID,
  261.     "mount",         -1,     MachUNIXError,
  262.     "umount",         -1,     MachUNIXError,
  263.     "old setuid",         -1,     MachUNIXError,
  264.     "getuid",         -1,     MachUNIXGetuid,
  265.     "old stime",         -1,     MachUNIXError,
  266.     "ptrace",         -1,     MachUNIXPtrace,
  267.     "old alarm",         -1,     MachUNIXError,
  268.     "old fstat",         -1,     MachUNIXError,
  269.     "old pause",         -1,     MachUNIXError,
  270.     "old utime",         -1,     MachUNIXError,
  271.     "old stty",         -1,     MachUNIXError,
  272.     "old gtty",         -1,     MachUNIXError,
  273.     "access",         -1,     MachUNIXAccess,
  274.     "old nice",         -1,     MachUNIXError,
  275.     "old ftime",         -1,     MachUNIXError,
  276.     "sync",            -1,     MachUNIXSync,
  277.     "kill",            -1,     MachUNIXKill,
  278.     "stat",            -1,     MachUNIXStat,
  279.     "old setpgrp",         -1,     MachUNIXError,
  280.     "lstat",        -1,     MachUNIXLstat,
  281.     "dup",             -1,     MachUNIXDup,
  282.     "pipe",            -1,     MachUNIXPipe,
  283.     "old times",        -1,     MachUNIXError,
  284.     "profil",         -1,     MachUNIXProfil,
  285.     "nosys",         -1,     MachUNIXError,
  286.     "old setgid",         -1,     MachUNIXError,
  287.     "getgid",         -1,     MachUNIXGetGID,
  288.     "old sig",         -1,     MachUNIXError,
  289.     "USG 1",         -1,     MachUNIXError,
  290.     "USG 2",         -1,     MachUNIXError,
  291.     "acct",         -1,     MachUNIXError,
  292.     "old set phys addr",     -1,     MachUNIXError,
  293.     "old syslock in core",    -1,     MachUNIXError,
  294.     "ioctl",         -1,     MachUNIXIoctl,
  295.     "reboot",         -1,     MachUNIXReboot,
  296.     "old mpxchan",         -1,     MachUNIXError,
  297.     "symlink",         -1,     MachUNIXSymlink,
  298.     "readlink",         -1,     MachUNIXReadLink,
  299.     "execve",         -1,     MachUNIXExecve,
  300.     "umask",         -1,     MachUNIXUmask,
  301.     "chroot",         -1,     MachUNIXError,
  302.     "fstat",         -1,     MachUNIXFstat,
  303.     "used internally",     -1,     MachUNIXError,
  304.     "getpagesize",         -1,     MachUNIXGetPageSize,
  305.     "mremap",         -1,     MachUNIXError,
  306.     "vfork",         -1,     MachUNIXVFork,
  307.     "old vread",         -1,     MachUNIXError,
  308.     "old vwrite",         -1,     MachUNIXError,
  309.     "new sbrk",        -1,     MachUNIXError,
  310.     "sstk",            -1,     MachUNIXError,
  311.     "mmap",         -1,     MachUNIXMmap,
  312.     "old vadvise",         -1,     MachUNIXError,
  313.     "munmap",         -1,     MachUNIXMunmap,
  314.     "mprotect",         -1,     MachUNIXError,
  315.     "madvise",         -1,     MachUNIXError,
  316.     "vhangup",         -1,     MachUNIXError,
  317.     "old vlimit",         -1,     MachUNIXError,
  318.     "mincore",         -1,     MachUNIXMincore,
  319.     "getgroups",         -1,     MachUNIXGetGroups,
  320.     "setgroups",         -1,     MachUNIXSetGroups,
  321.     "getpgrp",         -1,     MachUNIXGetPGrp,
  322.     "setpgrp",         -1,     MachUNIXSetPGrp,
  323.     "setitimer",         -1,     MachUNIXSetITimer,
  324.     "wait",            -1,     MachUNIXWait,
  325.     "swapon",         -1,     MachUNIXError,
  326.     "getitimer",         -1,    MachUNIXGetItimer,
  327.     "gethostname",         -1,     MachUNIXGetHostName,
  328.     "sethostname",         -1,     MachUNIXSetHostName,
  329.     "getdtablesize",     -1,    MachUNIXGetDTableSize,
  330.     "dup2",            -1,     MachUNIXDup2,
  331.     "getdopt",         -1,     MachUNIXGetDOpt,
  332.     "fcntl",         -1,     MachUNIXFcntl,
  333.     "select",         -1,     MachUNIXSelect,
  334.     "setdopt",         -1,     MachUNIXSetDOpt,
  335.     "fsync",         -1,     MachUNIXFSync,
  336.     "setpriority",         -1,     MachUNIXSetPriority,
  337.     "socket",         -1,     MachUNIXSocket,
  338.     "connect",         -1,     MachUNIXConnect,
  339.     "accept",         -1,     MachUNIXAccept,
  340.     "getpriority",         -1,    MachUNIXGetPriority,
  341.     "send",            -1,    MachUNIXSend,
  342.     "recv",            -1,     MachUNIXRecv,
  343.     "sigreturn",         -1,    MachUNIXLongJumpReturn,
  344.     "bind",            -1,    MachUNIXBind,
  345.     "setsockopt",         -1,     MachUNIXSetSockOpt,
  346.     "listen",         -1,     MachUNIXListen,
  347.     "old vtimes",         -1,    MachUNIXError,
  348.     "sigvec",         -1,     MachUNIXSigvec,
  349.     "sigblock",         -1,     MachUNIXBlock,
  350.     "sigsetmask",         -1,     MachUNIXSigSetmask,
  351.     "sigpause",         -1,     MachUNIXSigPause,
  352.     "sigstack",         -1,     MachUNIXSigStack,
  353.     "recvmsg",         -1,     MachUNIXRecvMsg,
  354.     "sendmsg",         -1,     MachUNIXSendMsg,
  355.     "#115",            -1,    MachUNIXError,
  356.     "gettimeofday",        -1,     MachUNIXGetTimeOfDay,
  357.     "getrusage",         -1,     MachUNIXGetRUsage,
  358.     "getsockopt",         -1,     MachUNIXGetSockOpt,
  359.     "#119",         -1,    MachUNIXError,
  360.     "readv",         -1,     MachUNIXReadv,
  361.     "writev",         -1,     MachUNIXWritev,
  362.     "settimeofday",        -1,     MachUNIXSetTimeOfDay,
  363.     "fchown",         -1,     MachUNIXFChown,
  364.     "fchmod",         -1,     MachUNIXFChmod,
  365.     "recvfrom",         -1,     MachUNIXRecvFrom,
  366.     "setreuid",         -1,     MachUNIXSetREUID,
  367.     "setregid",         -1,     MachUNIXSetREGID,
  368.     "rename",         -1,     MachUNIXRename,
  369.     "truncate",         -1,     MachUNIXTruncate,
  370.     "ftruncate",         -1,     MachUNIXFTruncate,
  371.     "flock",         -1,     MachUNIXFLock,
  372.     "#132",         -1,    MachUNIXError,
  373.     "sendto",        -1,     MachUNIXSendTo,
  374.     "shutdown",        -1,    MachUNIXShutdown,
  375.     "socketpair",        -1,    MachUNIXSocketPair,
  376.     "mkdir",        -1,    MachUNIXMkDir,
  377.     "rmdir",        -1,    MachUNIXRMDir,
  378.     "utimes",        -1,    MachUNIXUTimes,
  379.     "sigreturn(ljmp)",     -1,    MachUNIXLongJumpReturn,
  380.     "adjtime",         -1,     MachUNIXAdjTime,
  381.     "getpeername",        -1,     MachUNIXGetPeerName,
  382.     "gethostid",        -1,     MachUNIXGetHostID,
  383.     "sethostid",        -1,     MachUNIXSetHostID,
  384.     "getrlimit",        -1,     MachUNIXGetRLimit,
  385.     "setrlimit",        -1,     MachUNIXSetRLimit,
  386.     "killpg",        -1,     MachUNIXKillPG,
  387.     "#147",            -1,     MachUNIXError,
  388.     "setquota",         -1,     MachUNIXError,
  389.     "quota",        -1,     MachUNIXError,
  390.     "getsockname",      -1,     MachUNIXGetSockName,    
  391.     "sysmips",         -1,     MachUNIXError,
  392.     "cacheflush",        -1,     MachUNIXError,
  393.     "cachectl",        -1,     MachUNIXError,
  394.     "debug",        -1,     MachUNIXError,
  395.     "#155",            -1,     MachUNIXError,
  396.     "#156",            -1,     MachUNIXError,
  397.     "#157",            -1,     MachUNIXError,
  398.     "nfs_svc",         -1,     MachUNIXError,
  399.     "getdirentries",    -1,     MachUNIXGetDirEntries,
  400.     "#160",            -1,     MachUNIXError,
  401.     "#161",            -1,     MachUNIXError,
  402.     "#162",            -1,     MachUNIXError,
  403.     "nfs_biod",        -1,     MachUNIXError,
  404.     "nfs_getfh",        -1,     MachUNIXError,
  405.     "getdomainname",     -1,     MachUNIXGetDomainName,
  406.     "setdomainname",     -1,     MachUNIXSetDomainName,
  407.     "#167",            -1,     MachUNIXError,
  408.     "#168",            -1,     MachUNIXError,
  409.     "exportfs",        -1,     MachUNIXError,
  410.     "#170",            -1,     MachUNIXError,
  411.     "#171",            -1,     MachUNIXError,
  412.     "msgctl",        -1,     MachUNIXError,
  413.     "msgget",        -1,     MachUNIXError,
  414.     "msgrcv",        -1,     MachUNIXError,
  415.     "msgsnd",        -1,     MachUNIXError,
  416.     "semctl",        -1,     MachUNIXSemctl,
  417.     "semget",        -1,     MachUNIXSemget,
  418.     "semop",        -1,     MachUNIXSemop,
  419.     "uname",        -1,    MachUNIXError,
  420.     "shmsys",        -1,     MachUNIXError,
  421.     "plock",        -1,     MachUNIXError,
  422.     "lockf",        -1,     MachUNIXError,
  423.     "ustat",        -1,     MachUNIXError,
  424.     "getmnt",        -1,     MachUNIXError,
  425.     "mount",        -1,     MachUNIXError,
  426.     "umount",        -1,     MachUNIXError,
  427.     "sigpending",        -1,     MachUNIXError,
  428.     "#188",            -1,     MachUNIXError,
  429.     "#189",            -1,     MachUNIXError,
  430.     "#190",            -1,     MachUNIXError,
  431.     "#191",            -1,     MachUNIXError,
  432.     "#192",            -1,     MachUNIXError,
  433.     "#193",            -1,     MachUNIXError,
  434.     "#194",            -1,     MachUNIXError,
  435.     "#195",            -1,     MachUNIXError,
  436.     "#196",            -1,     MachUNIXError,
  437.     "#197",            -1,     MachUNIXError,
  438.     "#198",            -1,     MachUNIXError,
  439.     "#199",            -1,     MachUNIXError,
  440.     "#200",            -1,     MachUNIXError,
  441.     "#201",            -1,     MachUNIXError,
  442.     "#202",            -1,     MachUNIXError,
  443.     "#203",            -1,     MachUNIXError,
  444.     "#204",            -1,     MachUNIXError,
  445.     "#205",            -1,     MachUNIXError,
  446.     "#206",            -1,     MachUNIXError,
  447.     "#207",            -1,     MachUNIXError,
  448.     "#208",            -1,     MachUNIXError,
  449.     "#209",            -1,     MachUNIXError,
  450.     "#210",            -1,     MachUNIXError,
  451.     "#211",            -1,     MachUNIXError,
  452.     "#212",            -1,     MachUNIXError,
  453.     "#213",            -1,     MachUNIXError,
  454.     "#214",            -1,     MachUNIXError,
  455.     "#215",            -1,     MachUNIXError,
  456.     "#216",            -1,     MachUNIXError,
  457.     "#217",            -1,     MachUNIXError,
  458.     "#218",            -1,     MachUNIXError,
  459.     "#219",            -1,     MachUNIXError,
  460.     "#220",            -1,     MachUNIXError,
  461.     "#221",            -1,     MachUNIXError,
  462.     "#222",            -1,     MachUNIXError,
  463.     "#223",            -1,     MachUNIXError,
  464.     "#224",            -1,     MachUNIXError,
  465.     "#225",            -1,     MachUNIXError,
  466.     "#226",            -1,     MachUNIXError,
  467.     "#227",            -1,     MachUNIXError,
  468.     "#228",            -1,     MachUNIXError,
  469.     "#229",            -1,     MachUNIXError,
  470. #else
  471.     "indir",         0,     MachUNIXError,
  472.     "exit",            1,     MachUNIXExit,
  473.     "fork",            0,     MachUNIXFork,
  474.     "read",            3,     MachUNIXRead,
  475.     "write",         3,     MachUNIXWrite,
  476.     "open",            3,     MachUNIXOpen,
  477.     "close",         1,     MachUNIXClose,
  478.     "old wait",         0,     MachUNIXError,
  479.     "creat",         2,     MachUNIXCreat,
  480.     "link",            2,     MachUNIXLink,    
  481.     "unlink",         1,     MachUNIXUnlink,
  482.     "execv",         2,     MachUNIXExecv,
  483.     "chdir",         1,     MachUNIXChdir,
  484.     "old time",         0,     MachUNIXError,
  485.     "mknod",         3,     MachUNIXError,
  486.     "chmod",         2,     MachUNIXChmod,
  487.     "chown",         3,     MachUNIXChown, 
  488.     "sbrk",         1,     MachUNIXSbrk,
  489.     "old stat",         2,    MachUNIXError,
  490.     "lseek",         3,     MachUNIXLseek,
  491.     "getpid",         0,     MachUNIXGetPID,
  492.     "mount",         5,     MachUNIXError,
  493.     "umount",         1,     MachUNIXError,
  494.     "old setuid",         1,     MachUNIXError,
  495.     "getuid",         0,     MachUNIXGetuid,
  496.     "old stime",         1,     MachUNIXError,
  497.     "ptrace",         4,     MachUNIXPtrace,
  498.     "old alarm",         1,     MachUNIXError,
  499.     "old fstat",         2,     MachUNIXError,
  500.     "old pause",         0,     MachUNIXError,
  501.     "old utime",         2,     MachUNIXError,
  502.     "old stty",         0,     MachUNIXError,
  503.     "old gtty",         0,     MachUNIXError,
  504.     "access",         2,     MachUNIXAccess,
  505.     "old nice",         1,     MachUNIXError,
  506.     "old ftime",         1,     MachUNIXError,
  507.     "sync",            0,     MachUNIXSync,
  508.     "kill",            2,     MachUNIXKill,
  509.     "stat",            2,     MachUNIXStat,
  510.     "old setpgrp",         2,     MachUNIXError,
  511.     "lstat",        2,     MachUNIXLstat,
  512.     "dup",             1,     MachUNIXDup,
  513.     "pipe",            1,     MachUNIXPipe,
  514.     "old times",        1,     MachUNIXError,
  515.     "profil",         4,     MachUNIXProfil,
  516.     "nosys",         0,     MachUNIXError,
  517.     "old setgid",         1,     MachUNIXError,
  518.     "getgid",         0,     MachUNIXGetGID,
  519.     "old sig",         2,     MachUNIXError,
  520.     "USG 1",         0,     MachUNIXError,
  521.     "USG 2",         0,     MachUNIXError,
  522.     "acct",         1,     MachUNIXError,
  523.     "old set phys addr",     0,     MachUNIXError,
  524.     "old syslock in core",    0,     MachUNIXError,
  525.     "ioctl",         3,     MachUNIXIoctl,
  526.     "reboot",         1,     MachUNIXReboot,
  527.     "old mpxchan",         0,     MachUNIXError,
  528.     "symlink",         2,     MachUNIXSymlink,
  529.     "readlink",         3,     MachUNIXReadLink,
  530.     "execve",         3,     MachUNIXExecve,
  531.     "umask",         1,     MachUNIXUmask,
  532.     "chroot",         1,     MachUNIXError,
  533.     "fstat",         2,     MachUNIXFstat,
  534.     "used internally",     0,     MachUNIXError,
  535.     "getpagesize",         0,     MachUNIXGetPageSize,
  536.     "mremap",         5,     MachUNIXError,
  537.     "vfork",         0,     MachUNIXVFork,
  538.     "old vread",         0,     MachUNIXError,
  539.     "old vwrite",         0,     MachUNIXError,
  540.     "new sbrk",        1,     MachUNIXError,
  541.     "sstk",            1,     MachUNIXError,
  542.     "mmap",         6,     MachUNIXMmap,
  543.     "old vadvise",         1,     MachUNIXError,
  544.     "munmap",         2,     MachUNIXMunmap,
  545.     "mprotect",         3,     MachUNIXError,
  546.     "madvise",         3,     MachUNIXError,
  547.     "vhangup",         1,     MachUNIXError,
  548.     "old vlimit",         2,     MachUNIXError,
  549.     "mincore",         3,     MachUNIXMincore,
  550.     "getgroups",         2,     MachUNIXGetGroups,
  551.     "setgroups",         2,     MachUNIXSetGroups,
  552.     "getpgrp",         1,     MachUNIXGetPGrp,
  553.     "setpgrp",         2,     MachUNIXSetPGrp,
  554.     "setitimer",         3,     MachUNIXSetITimer,
  555.     "wait",            3,     MachUNIXWait,
  556.     "swapon",         1,     MachUNIXError,
  557.     "getitimer",         2,    MachUNIXGetItimer,
  558.     "gethostname",         2,     MachUNIXGetHostName,
  559.     "sethostname",         2,     MachUNIXSetHostName,
  560.     "getdtablesize",     0,    MachUNIXGetDTableSize,
  561.     "dup2",            2,     MachUNIXDup2,
  562.     "getdopt",         2,     MachUNIXGetDOpt,
  563.     "fcntl",         3,     MachUNIXFcntl,
  564.     "select",         5,     MachUNIXSelect,
  565.     "setdopt",         2,     MachUNIXSetDOpt,
  566.     "fsync",         1,     MachUNIXFSync,
  567.     "setpriority",         3,     MachUNIXSetPriority,
  568.     "socket",         3,     MachUNIXSocket,
  569.     "connect",         3,     MachUNIXConnect,
  570.     "accept",         3,     MachUNIXAccept,
  571.     "getpriority",         2,    MachUNIXGetPriority,
  572.     "send",            4,    MachUNIXSend,
  573.     "recv",            4,     MachUNIXRecv,
  574.     "sigreturn",         1,    MachUNIXLongJumpReturn,
  575.     "bind",            3,    MachUNIXBind,
  576.     "setsockopt",         5,     MachUNIXSetSockOpt,
  577.     "listen",         2,     MachUNIXListen,
  578.     "old vtimes",         2,    MachUNIXError,
  579.     "sigvec",         4,     MachUNIXSigvec,
  580.     "sigblock",         1,     MachUNIXBlock,
  581.     "sigsetmask",         1,     MachUNIXSigSetmask,
  582.     "sigpause",         1,     MachUNIXSigPause,
  583.     "sigstack",         2,     MachUNIXSigStack,
  584.     "recvmsg",         3,     MachUNIXRecvMsg,
  585.     "sendmsg",         3,     MachUNIXSendMsg,
  586.     "#115",            0,    MachUNIXError,
  587.     "gettimeofday",        2,     MachUNIXGetTimeOfDay,
  588.     "getrusage",         2,     MachUNIXGetRUsage,
  589.     "getsockopt",         5,     MachUNIXGetSockOpt,
  590.     "#119",         0,    MachUNIXError,
  591.     "readv",         3,     MachUNIXReadv,
  592.     "writev",         3,     MachUNIXWritev,
  593.     "settimeofday",        2,     MachUNIXSetTimeOfDay,
  594.     "fchown",         3,     MachUNIXFChown,
  595.     "fchmod",         2,     MachUNIXFChmod,
  596.     "recvfrom",         6,     MachUNIXRecvFrom,
  597.     "setreuid",         2,     MachUNIXSetREUID,
  598.     "setregid",         2,     MachUNIXSetREGID,
  599.     "rename",         2,     MachUNIXRename,
  600.     "truncate",         2,     MachUNIXTruncate,
  601.     "ftruncate",         2,     MachUNIXFTruncate,
  602.     "flock",         2,     MachUNIXFLock,
  603.     "#132",             0,    MachUNIXError,
  604.     "sendto",        6,     MachUNIXSendTo,
  605.     "shutdown",        2,    MachUNIXShutdown,
  606.     "socketpair",        5,    MachUNIXSocketPair,
  607.     "mkdir",        2,    MachUNIXMkDir,
  608.     "rmdir",        1,    MachUNIXRMDir,
  609.     "utimes",        2,    MachUNIXUTimes,
  610.     "sigreturn(ljmp)",     1,    MachUNIXLongJumpReturn,
  611.     "adjtime",         2,     MachUNIXAdjTime,
  612.     "getpeername",        3,     MachUNIXGetPeerName,
  613.     "gethostid",        2,     MachUNIXGetHostID,
  614.     "sethostid",        2,     MachUNIXSetHostID,
  615.     "getrlimit",        2,     MachUNIXGetRLimit,
  616.     "setrlimit",        2,     MachUNIXSetRLimit,
  617.     "killpg",        2,     MachUNIXKillPG,
  618.     "#147",            0,     MachUNIXError,
  619.     "setquota",         0,     MachUNIXError,
  620.     "quota",        0,     MachUNIXError,
  621.     "getsockname",      3,     MachUNIXGetSockName,    
  622.     "sysmips",         0,     MachUNIXError,
  623.     "cacheflush",        0,     MachUNIXError,
  624.     "cachectl",        0,     MachUNIXError,
  625.     "debug",        0,     MachUNIXError,
  626.     "#155",            0,     MachUNIXError,
  627.     "#156",            0,     MachUNIXError,
  628.     "#157",            0,     MachUNIXError,
  629.     "nfs_svc",         0,     MachUNIXError,
  630.     "getdirentries",    4,     MachUNIXGetDirEntries,
  631.     "#160",            0,     MachUNIXError,
  632.     "#161",            0,     MachUNIXError,
  633.     "#162",            0,     MachUNIXError,
  634.     "nfs_biod",        0,     MachUNIXError,
  635.     "nfs_getfh",        0,     MachUNIXError,
  636.     "getdomainname",     2,     MachUNIXGetDomainName,
  637.     "setdomainname",     2,     MachUNIXSetDomainName,
  638.     "#167",            0,     MachUNIXError,
  639.     "#168",            0,     MachUNIXError,
  640.     "exportfs",        0,     MachUNIXError,
  641.     "#170",            0,     MachUNIXError,
  642.     "#171",            0,     MachUNIXError,
  643.     "msgctl",        0,     MachUNIXError,
  644.     "msgget",        0,     MachUNIXError,
  645.     "msgrcv",        0,     MachUNIXError,
  646.     "msgsnd",        0,     MachUNIXError,
  647.     "semctl",        4,     MachUNIXSemctl,
  648.     "semget",        3,     MachUNIXSemget,
  649.     "semop",        3,     MachUNIXSemop,
  650.     "uname",        0,    MachUNIXError,
  651.     "shmsys",        0,     MachUNIXError,
  652.     "plock",        0,     MachUNIXError,
  653.     "lockf",        0,     MachUNIXError,
  654.     "ustat",        0,     MachUNIXError,
  655.     "getmnt",        0,     MachUNIXError,
  656.     "mount",        0,     MachUNIXError,
  657.     "umount",        0,     MachUNIXError,
  658.     "sigpending",        0,     MachUNIXError,
  659.     "#188",            0,     MachUNIXError,
  660.     "#189",            0,     MachUNIXError,
  661.     "#190",            0,     MachUNIXError,
  662.     "#191",            0,     MachUNIXError,
  663.     "#192",            0,     MachUNIXError,
  664.     "#193",            0,     MachUNIXError,
  665.     "#194",            0,     MachUNIXError,
  666.     "#195",            0,     MachUNIXError,
  667.     "#196",            0,     MachUNIXError,
  668.     "#197",            0,     MachUNIXError,
  669.     "#198",            0,     MachUNIXError,
  670.     "#199",            0,     MachUNIXError,
  671.     "#200",            0,     MachUNIXError,
  672.     "#201",            0,     MachUNIXError,
  673.     "#202",            0,     MachUNIXError,
  674.     "#203",            0,     MachUNIXError,
  675.     "#204",            0,     MachUNIXError,
  676.     "#205",            0,     MachUNIXError,
  677.     "#206",            0,     MachUNIXError,
  678.     "#207",            0,     MachUNIXError,
  679.     "#208",            0,     MachUNIXError,
  680.     "#209",            0,     MachUNIXError,
  681.     "#210",            0,     MachUNIXError,
  682.     "#211",            0,     MachUNIXError,
  683.     "#212",            0,     MachUNIXError,
  684.     "#213",            0,     MachUNIXError,
  685.     "#214",            0,     MachUNIXError,
  686.     "#215",            0,     MachUNIXError,
  687.     "#216",            0,     MachUNIXError,
  688.     "#217",            0,     MachUNIXError,
  689.     "#218",            0,     MachUNIXError,
  690.     "#219",            0,     MachUNIXError,
  691.     "#220",            0,     MachUNIXError,
  692.     "#221",            0,     MachUNIXError,
  693.     "#222",            0,     MachUNIXError,
  694.     "#223",            0,     MachUNIXError,
  695.     "#224",            0,     MachUNIXError,
  696.     "#225",            0,     MachUNIXError,
  697.     "#226",            0,     MachUNIXError,
  698.     "#227",            0,     MachUNIXError,
  699.     "#228",            0,     MachUNIXError,
  700.     "#229",            0,     MachUNIXError,
  701. #endif
  702.     "#230",            0,     MachUNIXError,
  703.     "#231",            0,     MachUNIXError,
  704.     "#232",            0,     MachUNIXError,
  705.     "#233",            0,     MachUNIXError,
  706.     "#234",            0,     MachUNIXError,
  707.     "#235",            0,     MachUNIXError,
  708.     "#236",            0,     MachUNIXError,
  709.     "#237",            0,     MachUNIXError,
  710.     "#238",            0,     MachUNIXError,
  711.     "#239",            0,     MachUNIXError,
  712.     "#240",            0,     MachUNIXError,
  713.     "#241",            0,     MachUNIXError,
  714.     "#242",            0,     MachUNIXError,
  715.     "#243",            0,     MachUNIXError,
  716.     "#244",            0,     MachUNIXError,
  717.     "#245",            0,     MachUNIXError,
  718.     "#246",            0,     MachUNIXError,
  719.     "#247",            0,     MachUNIXError,
  720.     "#248",            0,     MachUNIXError,
  721.     "#249",            0,     MachUNIXError,
  722.     "#250",            0,     MachUNIXError,
  723.     "#251",            0,     MachUNIXError,
  724.     "#252",            0,     MachUNIXError,
  725.     "#253",            0,     MachUNIXError,
  726.     "#254",            0,     MachUNIXError,
  727.     "#255",            0,     MachUNIXError,
  728.     "getsysinfo",        0,     MachUNIXGetSysInfo,
  729.     "setsysinfo",        0,     MachUNIXError,
  730. };
  731.  
  732. int machNumUNIXSyscalls = sizeof(machUNIXSysCallTable) / sizeof(SyscallInfo);
  733.  
  734. extern Mach_State    *machCurStatePtr;
  735.  
  736. #define UNIX_SIG_RETURN        103
  737. #define UNIX_LONG_JUMP_RETURN    139
  738.  
  739.  
  740. /*
  741.  * ----------------------------------------------------------------------------
  742.  *
  743.  * MachUNIXSyscall --
  744.  *
  745.  *    Try and handle the given UNIX system call.
  746.  *    Note that this routine is called only if (machUNIXSyscallTrace > 0)
  747.  *    or under special conditions.
  748.  *
  749.  * Results:
  750.  *    TRUE if this was really a UNIX system call.
  751.  *
  752.  * Side effects:
  753.  *    None.
  754.  *
  755.  * ----------------------------------------------------------------------------
  756.  */
  757. Boolean
  758. MachUNIXSyscall()
  759. {
  760.     unsigned        *regs;
  761.     int            args[6];
  762.     ReturnStatus    status;
  763.     int            type;
  764.     int            numArgs;
  765. #ifdef CANT_MIGRATE_COMPAT
  766.     Proc_ControlBlock    *procPtr;
  767. #endif /* CANT_MIGRATE_COMPAT */
  768.  
  769.     if (machNewUnixCompat) {
  770.     return MachUNIXSyscallNew();
  771.     }
  772.  
  773.     /*
  774.      * See if we got a UNIX system call.  Unix passes the system call type
  775.      * in v0.
  776.      */
  777.     type = machCurStatePtr->userState.regState.regs[V0];
  778.     if (type < 0 || type >= machNumUNIXSyscalls) {
  779.     printf("MachUNIXSyscall failed with type %d\n", type);
  780.     return(FALSE);
  781.     }
  782.  
  783. #ifdef CANT_MIGRATE_COMPAT
  784.     /*
  785.      * We don't want to migrate processes that are making unix-compatible calls.
  786.      */
  787.     procPtr = Proc_GetCurrentProc();
  788.     if (!(procPtr->genFlags & PROC_DONT_MIGRATE)) {
  789.     Proc_NeverMigrate(procPtr);
  790.     }
  791. #endif /* CANT_MIGRATE_COMPAT */
  792.     
  793.     numArgs = machUNIXSysCallTable[type].numArgs;
  794.     regs = machCurStatePtr->userState.regState.regs;
  795.     if (numArgs > 4) {
  796.     if (Vm_CopyIn(4 * (numArgs - 4), regs[SP] + 16, args) != SUCCESS) {
  797.         regs[V0] = Compat_MapCode(SYS_ARG_NOACCESS);
  798.         regs[A3] = 1;
  799.         return(TRUE);
  800.     }
  801.     }
  802.     machCurStatePtr->userState.unixRetVal = 0;
  803.     switch (numArgs) {
  804.     case 0:
  805.         if (machUNIXSyscallTrace > 1) {
  806.         printf("MachUNIXSyscall: %s() => ", 
  807.             machUNIXSysCallTable[type].name);
  808.         }
  809.         status = machUNIXSysCallTable[type].func();
  810.         break;
  811.     case 1:
  812.         if (machUNIXSyscallTrace > 1) {
  813.         printf("MachUNIXSyscall: %s(%x) => ", 
  814.             machUNIXSysCallTable[type].name,
  815.             regs[A0]);
  816.         }
  817.         status = machUNIXSysCallTable[type].func(regs[A0]);
  818.         break;
  819.     case 2:
  820.         if (machUNIXSyscallTrace > 1) {
  821.         printf("MachUNIXSyscall: %s(%x, %x) => ", 
  822.             machUNIXSysCallTable[type].name,
  823.             regs[A0], regs[A1]);
  824.         }
  825.         status = machUNIXSysCallTable[type].func(regs[A0], regs[A1]);
  826.         break;
  827.     case 3:
  828.         if (machUNIXSyscallTrace > 1) {
  829.         printf("MachUNIXSyscall: %s(%x, %x, %x) => ", 
  830.             machUNIXSysCallTable[type].name,
  831.             regs[A0], regs[A1], regs[A2]);
  832.         }
  833.         status = machUNIXSysCallTable[type].func(regs[A0], regs[A1],
  834.                          regs[A2]);
  835.         break;
  836.     case 4:
  837.         if (machUNIXSyscallTrace > 1) {
  838.         printf("MachUNIXSyscall: %s(%x, %x, %x, %x) => ", 
  839.             machUNIXSysCallTable[type].name,
  840.             regs[A0], regs[A1], regs[A2], regs[A3]);
  841.         }
  842.         status = machUNIXSysCallTable[type].func(regs[A0], regs[A1],
  843.                          regs[A2], regs[A3]);
  844.         break;
  845.     case 5: 
  846.         if (machUNIXSyscallTrace > 1) {
  847.         printf("MachUNIXSyscall: %s(%x, %x, %x, %x, %x) => ", 
  848.             machUNIXSysCallTable[type].name,
  849.             regs[A0], regs[A1], regs[A2], regs[A3], args[0]);
  850.         }
  851.         status = machUNIXSysCallTable[type].func(regs[A0], regs[A1],
  852.                          regs[A2], regs[A3], args[0]);
  853.         break; 
  854.     case 6:
  855.         if (machUNIXSyscallTrace > 1) {
  856.         printf("MachUNIXSyscall: %s(%x, %x, %x, %x, %x, %x) => ", 
  857.             machUNIXSysCallTable[type].name,
  858.             regs[A0], regs[A1], regs[A2], regs[A3], args[0],
  859.             args[1]);
  860.         }
  861.         status = machUNIXSysCallTable[type].func(regs[A0], regs[A1],
  862.                          regs[A2], regs[A3], args[0],
  863.                          args[1]);
  864.         break; 
  865.     case 7:
  866.         if (machUNIXSyscallTrace > 1) {
  867.         printf("MachUNIXSyscall: %s(%x, %x, %x, %x, %x, %x, %x) => ", 
  868.             machUNIXSysCallTable[type].name,
  869.             regs[A0], regs[A1], regs[A2], regs[A3], args[0],
  870.             args[1], args[2]);
  871.         }
  872.         status = machUNIXSysCallTable[type].func(regs[A0], regs[A1],
  873.                          regs[A2], regs[A3], args[0],
  874.                          args[1], args[2]);
  875.         break;
  876.     case 8:
  877.         if (machUNIXSyscallTrace > 1) {
  878.         printf("MachUNIXSyscall: %s(%x, %x, %x, %x, %x, %x, %x, %x) => ", 
  879.             machUNIXSysCallTable[type].name,
  880.             regs[A0], regs[A1], regs[A2], regs[A3], args[0],
  881.             args[1], args[2], args[3]);
  882.         }
  883.         status = machUNIXSysCallTable[type].func(regs[A0], regs[A1], 
  884.                          regs[A2], regs[A3], args[0],
  885.                          args[1], args[2], args[3]);
  886.     default:
  887.         return MachUNIXSyscallNew();
  888.         /*
  889.         panic("Too many args to UNIX system call\n");
  890.         */
  891.         break;
  892.     }
  893.     /* 
  894.      * The long jump and signal return system calls do things differently on
  895.      * a return.  Everyone else does the standard thing.
  896.      */
  897.     if (type != MACH_UNIX_LONG_JUMP_RETURN && type != MACH_UNIX_SIG_RETURN) {
  898.     /*
  899.      * The UNIX stubs looks at a3 to decide what to do.  If a3 == 1 then
  900.      * v0 has the UNIX error code and the stub will stuff the error
  901.      * into errno.  If a3 == 0 the V0 has the return value.
  902.      */
  903.     if (status == GEN_ABORTED_BY_SIGNAL) {
  904.         printf("System call interrupted by signal\n");
  905.     }
  906.     if (status == SUCCESS) {
  907.         regs[V0] = machCurStatePtr->userState.unixRetVal;
  908.         regs[A3] = 0;
  909.     } else {
  910.         regs[V0] = Compat_MapCode(status);
  911.         regs[A3] = 1;
  912.     }
  913.     if (machUNIXSyscallTrace > 1) {
  914.         printf("V0 = %x A3 = %x\n", regs[V0], regs[A3]);
  915.     }
  916.     }
  917.     machCurStatePtr->userState.regState.pc += 4;
  918.  
  919.     return(TRUE);
  920. }
  921.  
  922.  
  923.  
  924. /*
  925.  * ----------------------------------------------------------------------------
  926.  *
  927.  * MachUNIXSyscallNew --
  928.  *
  929.  *    Try and handle the new given UNIX system call.
  930.  *    Note that this routine is called only if (machUNIXSyscallTrace > 0)
  931.  *    or under special conditions.
  932.  *
  933.  * Results:
  934.  *    TRUE if this was really a UNIX system call.
  935.  *
  936.  * Side effects:
  937.  *    None.
  938.  *
  939.  * ----------------------------------------------------------------------------
  940.  */
  941. Boolean
  942. MachUNIXSyscallNew()
  943. {
  944.     unsigned        *regs;
  945.     int            args[6];
  946.     ReturnStatus    status;
  947.     int            type;
  948.     int            numArgs;
  949. #ifdef CANT_MIGRATE_COMPAT
  950.     Proc_ControlBlock    *procPtr;
  951. #endif /* CANT_MIGRATE_COMPAT */
  952.  
  953.     /*
  954.      * See if we got a UNIX system call.  Unix passes the system call type
  955.      * in v0.
  956.      */
  957.     type = machCurStatePtr->userState.regState.regs[V0];
  958.     machCurStatePtr->userState.savedV0 = type;
  959.     machCurStatePtr->userState.savedA3 =
  960.         machCurStatePtr->userState.regState.regs[A3];
  961.     if (type < 0 || type >= MACH_MAX_UNIX_SYSCALL) {
  962.     printf("MachUNIXSyscallNew failed with type %d\n", type);
  963.     return(FALSE);
  964.     }
  965.  
  966. #ifdef CANT_MIGRATE_COMPAT
  967.     /*
  968.      * We don't want to migrate processes that are making unix-compatible calls.
  969.      */
  970.     procPtr = Proc_GetCurrentProc();
  971.     if (!(procPtr->genFlags & PROC_DONT_MIGRATE)) {
  972.     Proc_NeverMigrate(procPtr);
  973.     }
  974. #endif /* CANT_MIGRATE_COMPAT */
  975.     
  976.     numArgs = sysUnixSysCallTable[type].numArgs;
  977.     regs = machCurStatePtr->userState.regState.regs;
  978.     if (numArgs > 4) {
  979.     if (Vm_CopyIn(4 * (numArgs - 4), regs[SP] + 16, args) != SUCCESS) {
  980.         regs[V0] = Compat_MapCode(SYS_ARG_NOACCESS);
  981.         regs[A3] = 1;
  982.         return(TRUE);
  983.     }
  984.     }
  985.     switch (numArgs) {
  986.     case 0:
  987.         if (machUNIXSyscallTrace > 1) {
  988.         printf("MachUNIXSyscallNew: %s() => ", 
  989.             machUNIXSysCallTable[type].name);
  990.         }
  991.         status = sysUnixSysCallTable[type].func();
  992.         break;
  993.     case 1:
  994.         if (machUNIXSyscallTrace > 1) {
  995.         printf("MachUNIXSyscallNew: %s(%x) => ", 
  996.             machUNIXSysCallTable[type].name,
  997.             regs[A0]);
  998.         }
  999.         status = sysUnixSysCallTable[type].func(regs[A0]);
  1000.         break;
  1001.     case 2:
  1002.         if (machUNIXSyscallTrace > 1) {
  1003.         printf("MachUNIXSyscallNew: %s(%x, %x) => ", 
  1004.             machUNIXSysCallTable[type].name,
  1005.             regs[A0], regs[A1]);
  1006.         }
  1007.         status = sysUnixSysCallTable[type].func(regs[A0], regs[A1]);
  1008.         break;
  1009.     case 3:
  1010.         if (machUNIXSyscallTrace > 1) {
  1011.         printf("MachUNIXSyscallNew: %s(%x, %x, %x) => ", 
  1012.             machUNIXSysCallTable[type].name,
  1013.             regs[A0], regs[A1], regs[A2]);
  1014.         }
  1015.         status = sysUnixSysCallTable[type].func(regs[A0], regs[A1],
  1016.                          regs[A2]);
  1017.         break;
  1018.     case 4:
  1019.         if (machUNIXSyscallTrace > 1) {
  1020.         printf("MachUNIXSyscallNew: %s(%x, %x, %x, %x) => ", 
  1021.             machUNIXSysCallTable[type].name,
  1022.             regs[A0], regs[A1], regs[A2], regs[A3]);
  1023.         }
  1024.         status = sysUnixSysCallTable[type].func(regs[A0], regs[A1],
  1025.                          regs[A2], regs[A3]);
  1026.         break;
  1027.     case 5: 
  1028.         if (machUNIXSyscallTrace > 1) {
  1029.         printf("MachUNIXSyscallNew: %s(%x, %x, %x, %x, %x) => ", 
  1030.             machUNIXSysCallTable[type].name,
  1031.             regs[A0], regs[A1], regs[A2], regs[A3], args[0]);
  1032.         }
  1033.         status = sysUnixSysCallTable[type].func(regs[A0], regs[A1],
  1034.                          regs[A2], regs[A3], args[0]);
  1035.         break; 
  1036.     case 6:
  1037.         if (machUNIXSyscallTrace > 1) {
  1038.         printf("MachUNIXSyscallNew: %s(%x, %x, %x, %x, %x, %x) => ", 
  1039.             machUNIXSysCallTable[type].name,
  1040.             regs[A0], regs[A1], regs[A2], regs[A3], args[0],
  1041.             args[1]);
  1042.         }
  1043.         status = sysUnixSysCallTable[type].func(regs[A0], regs[A1],
  1044.                          regs[A2], regs[A3], args[0],
  1045.                          args[1]);
  1046.         break; 
  1047.     case 7:
  1048.         if (machUNIXSyscallTrace > 1) {
  1049.         printf("MachUNIXSyscallNew: %s(%x, %x, %x, %x, %x, %x, %x) => ", 
  1050.             machUNIXSysCallTable[type].name,
  1051.             regs[A0], regs[A1], regs[A2], regs[A3], args[0],
  1052.             args[1], args[2]);
  1053.         }
  1054.         status = sysUnixSysCallTable[type].func(regs[A0], regs[A1],
  1055.                          regs[A2], regs[A3], args[0],
  1056.                          args[1], args[2]);
  1057.         break;
  1058.     case 8:
  1059.         if (machUNIXSyscallTrace > 1) {
  1060.         printf("MachUNIXSyscallNew: %s(%x, %x, %x, %x, %x, %x, %x, %x) => ", 
  1061.             machUNIXSysCallTable[type].name,
  1062.             regs[A0], regs[A1], regs[A2], regs[A3], args[0],
  1063.             args[1], args[2], args[3]);
  1064.         }
  1065.         status = sysUnixSysCallTable[type].func(regs[A0], regs[A1], 
  1066.                          regs[A2], regs[A3], args[0],
  1067.                          args[1], args[2], args[3]);
  1068.     default:
  1069.         panic("Too many args to UNIX system call\n");
  1070.         break;
  1071.     }
  1072.     /*
  1073.      * The UNIX stubs looks at a3 to decide what to do.  If a3 == 1 then
  1074.      * v0 has the UNIX error code and the stub will stuff the error
  1075.      * into errno.  If a3 == 0 the V0 has the return value.
  1076.      */
  1077.     if (type != MACH_UNIX_LONG_JUMP_RETURN && type != MACH_UNIX_SIG_RETURN) {
  1078.     if (status >= 0) {
  1079.         regs[V0] = status;
  1080.         regs[A3] = 0;
  1081.     } else {
  1082.         regs[V0] = Proc_GetActualProc()->unixErrno;
  1083.         regs[A3] = 1;
  1084.     }
  1085.     }
  1086.     if (machUNIXSyscallTrace > 1) {
  1087.     printf("V0 = %x A3 = %x\n", regs[V0], regs[A3]);
  1088.     }
  1089.  
  1090.     machCurStatePtr->userState.regState.pc += 4;
  1091.  
  1092.     return(TRUE);
  1093. }
  1094.  
  1095. ReturnStatus
  1096. MachUNIXExit(status)
  1097.     int    status;
  1098. {
  1099.     Proc_Exit(status);
  1100.     return(FAILURE);
  1101. }
  1102.  
  1103. ReturnStatus
  1104. MachUNIXFork()
  1105. {
  1106.     ReturnStatus    status;
  1107.     Address        usp;
  1108.  
  1109.     usp = (Address) (machCurStatePtr->userState.regState.regs[SP] - 4);
  1110.  
  1111.     /*
  1112.      * Put the right values in V1 and A3 for the child because the process
  1113.      * jumps directly to user space after it is created.  A 1 in v1 
  1114.      * is what the system call stub in the user process expects for the
  1115.      * child.
  1116.      */
  1117.     machCurStatePtr->userState.regState.regs[V1] = 1;
  1118.     machCurStatePtr->userState.regState.regs[A3] = 0;
  1119.  
  1120.     status = Proc_Fork(FALSE, (int *)usp);
  1121.     if (status == PROC_CHILD_PROC) {
  1122.     printf("MachUNIXFork: Child came alive here?\n");
  1123.     return(SUCCESS);
  1124.     }
  1125.     if (status == SUCCESS) {
  1126.     (void)Vm_CopyIn(sizeof(int), usp, 
  1127.         (Address)&machCurStatePtr->userState.unixRetVal);
  1128.     }
  1129.     /* 
  1130.      * The user fork stub expects a 0 for the parent.
  1131.      */
  1132.     machCurStatePtr->userState.regState.regs[V1] = 0;
  1133.     return(status);
  1134. }
  1135.  
  1136.  
  1137. ReturnStatus
  1138. MachUNIXVFork()
  1139. {
  1140.     ReturnStatus    status;
  1141.     Address        usp;
  1142.  
  1143.     usp = (Address) (machCurStatePtr->userState.regState.regs[SP] - 4);
  1144.  
  1145.     /*
  1146.      * Put the right values in V1 and A3 for the child because the process
  1147.      * jumps directly to user space after it is created.  A 1 in v1 
  1148.      * is what the system call stub in the user process expects for the
  1149.      * child.
  1150.      */
  1151.     machCurStatePtr->userState.regState.regs[V1] = 1;
  1152.     machCurStatePtr->userState.regState.regs[A3] = 0;
  1153.  
  1154.     status = Proc_Fork(TRUE, (int *)usp);
  1155.     if (status == PROC_CHILD_PROC) {
  1156.     printf("MachUNIXFork: Child came alive here?\n");
  1157.     return(SUCCESS);
  1158.     }
  1159.     if (status == SUCCESS) {
  1160.     (void)Vm_CopyIn(sizeof(int), usp, 
  1161.             (Address)&machCurStatePtr->userState.unixRetVal);
  1162.     } 
  1163.     /* 
  1164.      * The user fork stub expects a 0 for the parent.
  1165.      */
  1166.     machCurStatePtr->userState.regState.regs[V1] = 0;
  1167.     return(status);
  1168. }
  1169.  
  1170. ReturnStatus
  1171. MachUNIXRead(streamID, buffer, numBytes)
  1172.     int     streamID;    /* descriptor for stream to read */
  1173.     char    *buffer;    /* pointer to buffer area */
  1174.     int        numBytes;    /* number of bytes to read */
  1175. {
  1176.     ReturnStatus    status;
  1177.     Address        usp;
  1178.  
  1179.     usp = (Address) (machCurStatePtr->userState.regState.regs[SP] - 4);
  1180.     status = Fs_ReadStub(streamID, numBytes, buffer, (int *)usp);
  1181.     if (status == SUCCESS) {
  1182.     (void)Vm_CopyIn(sizeof(int), usp, 
  1183.             (Address)&machCurStatePtr->userState.unixRetVal);
  1184.     }
  1185.     if (status == GEN_ABORTED_BY_SIGNAL) {
  1186.     printf("Read blown away by signal\n");
  1187.     }
  1188.     return(status);
  1189. }
  1190.  
  1191.  
  1192. ReturnStatus
  1193. MachUNIXWrite(streamID, buffer, numBytes)
  1194.     int     streamID;    /* descriptor for stream to read */
  1195.     char    *buffer;    /* pointer to buffer area */
  1196.     int        numBytes;    /* number of bytes to read */
  1197. {
  1198.     ReturnStatus    status;
  1199.     Address        usp;
  1200.  
  1201.     usp = (Address) (machCurStatePtr->userState.regState.regs[SP] - 4);
  1202.     status = Fs_WriteStub(streamID, numBytes, buffer, (int *)usp);
  1203.     if (status == SUCCESS) {
  1204.     (void)Vm_CopyIn(sizeof(int), usp, 
  1205.             (Address)&machCurStatePtr->userState.unixRetVal);
  1206.     }
  1207.     if (status == GEN_ABORTED_BY_SIGNAL) {
  1208.     printf("Write blown away by signal\n");
  1209.     }
  1210.     return(status);
  1211. }
  1212.  
  1213. ReturnStatus
  1214. MachUNIXOpen(pathName, unixFlags, permissions)
  1215.     char    *pathName;    /* The name of the file to open */
  1216.     int        unixFlags;    /* O_RDONLY O_WRONLY O_RDWR O_NDELAY
  1217.                  * O_APPEND O_CREAT O_TRUNC O_EXCL */
  1218.     int        permissions;    /* Permission mask to use on creation */
  1219. {
  1220.     ReturnStatus status;    /* result returned by Fs_Open */
  1221.     register int useFlags = 0;    /* Sprite version of flags */
  1222.     Address        usp;
  1223.  
  1224.     /*
  1225.      * Convert unixFlags to FS_READ, etc.
  1226.      */
  1227.      
  1228.     if (unixFlags & FASYNC) {
  1229.     printf("open - FASYNC not supported\n");
  1230.     return(SYS_INVALID_ARG);
  1231.     }
  1232.     if (unixFlags & O_RDWR) {
  1233.     useFlags |= FS_READ|FS_WRITE;
  1234.     } else if (unixFlags & O_WRONLY) {
  1235.     useFlags |= FS_WRITE;
  1236.     } else {
  1237.     useFlags |= FS_READ;
  1238.     }
  1239.     if (unixFlags & FNDELAY) {
  1240.     useFlags |= FS_NON_BLOCKING;
  1241.     }
  1242.     if (unixFlags & FAPPEND) {
  1243.     useFlags |= FS_APPEND;
  1244.     }
  1245.     if (unixFlags & FTRUNC) {
  1246.     useFlags |= FS_TRUNC;
  1247.     }
  1248.     if (unixFlags & FEXCL) {
  1249.     useFlags |= FS_EXCLUSIVE;
  1250.     }
  1251.     if (unixFlags & O_MASTER) {
  1252.     useFlags |= FS_PDEV_MASTER;
  1253.     }
  1254.     if (unixFlags & O_PFS_MASTER) {
  1255.     useFlags |= FS_PFS_MASTER;
  1256.     }
  1257.     if (unixFlags & FCREAT) {
  1258.     useFlags |= FS_CREATE;
  1259.     }
  1260.  
  1261.     usp = (Address) (machCurStatePtr->userState.regState.regs[SP] - 4);
  1262.  
  1263.     status = Fs_OpenStub(pathName, useFlags, permissions, (int *)usp);
  1264.     if (status == SUCCESS) {
  1265.     (void)Vm_CopyIn(sizeof(int), usp,
  1266.             (Address)&machCurStatePtr->userState.unixRetVal);
  1267.     }
  1268.     return(status);
  1269. }
  1270.  
  1271. ReturnStatus
  1272. MachUNIXClose(streamID)
  1273.     int streamID;
  1274. {
  1275.     return(Fs_UserClose(streamID));
  1276. }
  1277.  
  1278. ReturnStatus
  1279. MachUNIXCreat(pathName, permissions)
  1280.     char *pathName;        /* The name of the file to create */
  1281.     int permissions;        /* Permission mask to use on creation */
  1282. {
  1283.     return(MachUNIXOpen(pathName,  FS_CREATE|FS_TRUNC|FS_WRITE,
  1284.             permissions));
  1285. }
  1286.  
  1287. ReturnStatus
  1288. MachUNIXLink(name1, name2)
  1289.     char *name1;
  1290.     char *name2;
  1291. {
  1292.     return(Fs_HardLinkStub(name1, name2));
  1293. }
  1294.  
  1295. ReturnStatus
  1296. MachUNIXUnlink(pathName)
  1297.     char *pathName;
  1298. {
  1299.     return(Fs_RemoveStub(pathName));
  1300. }
  1301.  
  1302. ReturnStatus
  1303. MachUNIXExecve(name, argv, envp)
  1304.     char *name;            /* name of file to exec */
  1305.     char *argv[];        /* array of arguments */
  1306.     char *envp[];        /* array of environment pointers */
  1307. {
  1308.     return(Proc_ExecEnv(name, argv, envp, FALSE));
  1309. }
  1310.  
  1311. ReturnStatus
  1312. MachUNIXExecv(name, argv)
  1313.     char *name;            /* Name of file containing program to exec. */
  1314.     char **argv;        /* Array of arguments to pass to program. */
  1315. {
  1316.     return(Proc_Exec(name, argv, FALSE));
  1317. }
  1318.  
  1319. ReturnStatus
  1320. MachUNIXChdir(pathName)
  1321.     char    *pathName;
  1322. {
  1323.     return(Fs_ChangeDirStub(pathName));
  1324. }
  1325.  
  1326. ReturnStatus
  1327. MachUNIXChmod(path, mode)
  1328.     char    *path;
  1329.     int        mode;
  1330. {
  1331.     Fs_Attributes    attributes;
  1332.     Address        usp;
  1333.     ReturnStatus    status;
  1334.  
  1335.     usp = (Address) (machCurStatePtr->userState.regState.regs[SP] - 
  1336.              sizeof(Fs_Attributes));
  1337.  
  1338.     attributes.permissions = mode;
  1339.     status = Vm_CopyOut(sizeof(Fs_Attributes), (Address)&attributes, usp);
  1340.     if (status == SUCCESS) {
  1341.     status = Fs_SetAttrStub(path,  FS_ATTRIB_FILE, (Fs_Attributes *)usp, 
  1342.                     FS_SET_MODE);
  1343.     }
  1344.     return(status);
  1345. }
  1346.  
  1347. ReturnStatus
  1348. MachUNIXFChmod(fd, mode)
  1349.     int        fd;
  1350.     int        mode;
  1351. {
  1352.     Fs_Attributes    attributes;
  1353.     Address        usp;
  1354.     ReturnStatus    status;
  1355.  
  1356.     usp = (Address) (machCurStatePtr->userState.regState.regs[SP] - 
  1357.              sizeof(Fs_Attributes));
  1358.  
  1359.     attributes.permissions = mode;
  1360.     status = Vm_CopyOut(sizeof(Fs_Attributes), (Address)&attributes, usp);
  1361.     if (status == SUCCESS) {
  1362.     status = Fs_SetAttrIDStub(fd, (Fs_Attributes *)usp, FS_SET_MODE);
  1363.     }
  1364.     return(status);
  1365. }
  1366.  
  1367. ReturnStatus
  1368. MachUNIXChown(path, owner, group)
  1369.     char *path;
  1370.     int owner;
  1371.     int group;
  1372. {
  1373.     ReturnStatus status;    /* result returned by Sprite system calls */
  1374.     Fs_Attributes attributes;    /* struct containing all file attributes.
  1375.                  * only ownership is looked at. */
  1376.     Address        usp;
  1377.  
  1378.     usp = (Address) (machCurStatePtr->userState.regState.regs[SP] - 
  1379.              sizeof(Fs_Attributes));
  1380.  
  1381.     attributes.uid = owner;
  1382.     attributes.gid = group;
  1383.     status = Vm_CopyOut(sizeof(Fs_Attributes), (Address)&attributes, usp);
  1384.     if (status == SUCCESS) {
  1385.     status = Fs_SetAttrStub(path,  FS_ATTRIB_LINK, (Fs_Attributes *)usp,
  1386.                     FS_SET_OWNER);
  1387.     }
  1388.     return(status);
  1389. }
  1390.  
  1391. ReturnStatus
  1392. MachUNIXFChown(fd, owner, group)
  1393.     int fd;
  1394.     int owner;
  1395.     int group;
  1396. {
  1397.     ReturnStatus status;    /* result returned by Sprite system calls */
  1398.     Fs_Attributes attributes;    /* struct containing all file attributes.
  1399.                  * only ownership is looked at. */
  1400.     Address        usp;
  1401.  
  1402.     usp = (Address) (machCurStatePtr->userState.regState.regs[SP] - 
  1403.              sizeof(Fs_Attributes));
  1404.  
  1405.     attributes.uid = owner;
  1406.     attributes.gid = group;
  1407.     status = Vm_CopyOut(sizeof(Fs_Attributes), (Address)&attributes, usp);
  1408.     if (status == SUCCESS) {
  1409.     status = Fs_SetAttrIDStub(fd,  (Fs_Attributes *)usp, FS_SET_OWNER);
  1410.     }
  1411.     return(status);
  1412. }
  1413.  
  1414. ReturnStatus
  1415. MachUNIXSbrk(addr)
  1416.     Address    addr;
  1417. {
  1418.     Vm_Segment    *segPtr;
  1419.     Address    lastAddr;
  1420.     Proc_ControlBlock    *procPtr;
  1421.  
  1422.     /*
  1423.      * The UNIX brk and sbrk call stubs figure where the end of the
  1424.      * heap is and they always call us with the new end of data segment.
  1425.      */
  1426.     procPtr = Proc_GetCurrentProc();
  1427.     segPtr = procPtr->vmPtr->segPtrArray[VM_HEAP];
  1428.     if (segPtr != (Vm_Segment *)NIL) {
  1429.     lastAddr =
  1430.         (Address) ((segPtr->offset + segPtr->numPages) * vm_PageSize);
  1431.     return(Vm_CreateVA(lastAddr, addr - lastAddr));
  1432.     }
  1433.     return(FAILURE);
  1434. }
  1435.  
  1436. ReturnStatus
  1437. MachUNIXLseek(streamID, offset, whence)
  1438.     int streamID;            /* array of stream identifiers */
  1439.     long offset;
  1440.     int whence;
  1441. {
  1442.     ReturnStatus    status;
  1443.     Ioc_RepositionArgs args;
  1444.     Address        usp;
  1445.  
  1446.     switch(whence) {
  1447.     case L_SET:
  1448.         args.base = IOC_BASE_ZERO;
  1449.         break;
  1450.     case L_INCR:
  1451.         args.base = IOC_BASE_CURRENT;
  1452.         break;
  1453.     case L_XTND:
  1454.         args.base = IOC_BASE_EOF;
  1455.         break;
  1456.     default:
  1457.         return(SYS_INVALID_ARG);
  1458.     }
  1459.     args.offset = offset;
  1460.     usp = (Address) (machCurStatePtr->userState.regState.regs[SP] - 4);
  1461.     status = Fs_IOControlStub(streamID, IOC_REPOSITION, 
  1462.                   sizeof(Ioc_RepositionArgs),
  1463.                   (Address)&args, sizeof(int), usp);
  1464.     if (status == SUCCESS) {
  1465.     (void)Vm_CopyIn(sizeof(int), usp,
  1466.             (Address)&machCurStatePtr->userState.unixRetVal);
  1467.     }
  1468.     return(status);
  1469. }
  1470.  
  1471. ReturnStatus
  1472. MachUNIXGetPID()
  1473. {
  1474. #ifdef notdef
  1475.     ReturnStatus    status;
  1476.     Address        usp;
  1477.  
  1478.     usp = (Address) (machCurStatePtr->userState.regState.regs[SP] - 4);
  1479.     status = Proc_GetIDs((int *)usp, (int *) NULL, (int *) NULL, (int *) NULL);
  1480.     if (status == SUCCESS) {
  1481.     (void)Vm_CopyIn(sizeof(int), usp,
  1482.             (Address)&machCurStatePtr->userState.unixRetVal);
  1483.     }
  1484.     return(status);
  1485. #endif
  1486.     register    Proc_ControlBlock    *procPtr;
  1487.  
  1488.     procPtr = Proc_GetEffectiveProc();
  1489.     machCurStatePtr->userState.unixRetVal = procPtr->processID;
  1490.     return(SUCCESS);
  1491. }
  1492.  
  1493. ReturnStatus
  1494. MachUNIXGetuid()
  1495. {
  1496.     ReturnStatus    status;
  1497.     Address        usp;
  1498.  
  1499.     usp = (Address) (machCurStatePtr->userState.regState.regs[SP] - 4);
  1500.     status = Proc_GetIDs((int *) NULL, (int *) NULL, (int *)usp, (int *) NULL);
  1501.     if (status == SUCCESS) {
  1502.     (void)Vm_CopyIn(sizeof(int), usp,
  1503.             (Address)&machCurStatePtr->userState.unixRetVal);
  1504.     }
  1505.     return(status);
  1506. }
  1507.  
  1508. ReturnStatus
  1509. MachUNIXAccess(pathName, mode)
  1510.     char *pathName;        /* The name of the file to open */
  1511.     int     mode;            /* access mode to test for */
  1512. {
  1513.     int spriteMode;
  1514.  
  1515.     if (mode == F_OK) {
  1516.     spriteMode = FS_EXISTS;
  1517.     } else {
  1518.     spriteMode = ((mode&R_OK)?FS_READ:0) | ((mode&W_OK)?FS_WRITE:0) |
  1519.         ((mode&X_OK)?FS_EXECUTE:0);
  1520.     }
  1521.     return(Fs_CheckAccess(pathName, spriteMode, TRUE));
  1522. }
  1523.  
  1524. ReturnStatus MachUNIXKill(pid, sig)
  1525.     int pid;
  1526.     int sig;
  1527. {
  1528.     ReturnStatus status;
  1529.     int         spriteSignal;
  1530.  
  1531.     status = Compat_UnixSignalToSprite(sig, &spriteSignal);
  1532.     if (status == FAILURE || (spriteSignal == NULL && sig != 0)) {
  1533.     return(SYS_INVALID_ARG);
  1534.     }
  1535.     if (pid == 0) {
  1536.     pid = PROC_MY_PID;
  1537.     }
  1538.     return(Sig_UserSend(spriteSignal, pid, FALSE));
  1539. }
  1540.  
  1541. ReturnStatus MachUNIXStat(pathName, attsBufPtr)
  1542.     char *pathName;        /* The name of the file to stat */
  1543.     struct stat *attsBufPtr;    /* ptr to buffer to hold attributes in 
  1544.                    Unix format */
  1545. {
  1546.     ReturnStatus     status;    /* status returned by Fs_GetAttributes */
  1547.     Fs_Attributes    spriteAtts;    /* buffer for attributes using
  1548.                        Sprite format. */
  1549.     Address        usp;
  1550.  
  1551.     usp = (Address)(machCurStatePtr->userState.regState.regs[SP] - 
  1552.             sizeof(Fs_Attributes));
  1553.  
  1554.     status = Fs_GetAttributesStub(pathName, FS_ATTRIB_FILE,
  1555.                   (Fs_Attributes *)usp);
  1556.     if (status != SUCCESS) {
  1557.     return(status);
  1558.     }
  1559.     (void)Vm_CopyIn(sizeof(Fs_Attributes), (Address)usp, (Address)&spriteAtts);
  1560.     return(CvtSpriteToUnixAtts(&spriteAtts, attsBufPtr));
  1561. }
  1562.  
  1563.  
  1564. ReturnStatus MachUNIXLstat(pathName, attsBufPtr)
  1565.     char *pathName;        /* The name of the file to stat */
  1566.     struct stat *attsBufPtr;    /* ptr to buffer to hold attributes in 
  1567.                    Unix format */
  1568. {
  1569.     ReturnStatus     status;    /* status returned by Fs_GetAttributes */
  1570.     Fs_Attributes    spriteAtts;    /* buffer for attributes using
  1571.                        Sprite format. */
  1572.     Address        usp;
  1573.  
  1574.     usp = (Address)(machCurStatePtr->userState.regState.regs[SP] - 
  1575.             sizeof(Fs_Attributes));
  1576.  
  1577.     status = Fs_GetAttributesStub(pathName, FS_ATTRIB_LINK,
  1578.                   (Fs_Attributes *)usp);
  1579.     if (status != SUCCESS) {
  1580.     return(status);
  1581.     }
  1582.     (void)Vm_CopyIn(sizeof(Fs_Attributes), (Address)usp, (Address)&spriteAtts);
  1583.     /*
  1584.      * See if we just got a remote link.  If so turn around and do a normal
  1585.      * stat because in compatibility mode we want to follow remote links.
  1586.      */
  1587.     if (spriteAtts.type == FS_REMOTE_LINK) {
  1588.     status = Fs_GetAttributesStub(pathName, FS_ATTRIB_FILE,
  1589.                       (Fs_Attributes *)usp);
  1590.     if (status != SUCCESS) {
  1591.         return(status);
  1592.     }
  1593.     (void)Vm_CopyIn(sizeof(Fs_Attributes), (Address)usp, 
  1594.             (Address)&spriteAtts);
  1595.     }
  1596.  
  1597.     return(CvtSpriteToUnixAtts(&spriteAtts, attsBufPtr));
  1598. }
  1599.  
  1600.  
  1601. ReturnStatus MachUNIXFstat(fd, attsBufPtr)
  1602.     int    fd;        /* The name of the file to stat */
  1603.     struct stat *attsBufPtr;    /* ptr to buffer to hold attributes in 
  1604.                    Unix format */
  1605. {
  1606.     ReturnStatus     status;    /* status returned by Fs_GetAttributes */
  1607.     Fs_Attributes    spriteAtts;    /* buffer for attributes using
  1608.                        Sprite format. */
  1609.     Address        usp;
  1610.  
  1611.     usp = (Address)(machCurStatePtr->userState.regState.regs[SP] - 
  1612.             sizeof(Fs_Attributes));
  1613.  
  1614.     status = Fs_GetAttributesIDStub(fd, (Fs_Attributes *)usp);
  1615.     if (status != SUCCESS) {
  1616.     return(status);
  1617.     }
  1618.     (void)Vm_CopyIn(sizeof(Fs_Attributes), (Address)usp, (Address)&spriteAtts);
  1619.     return(CvtSpriteToUnixAtts(&spriteAtts, attsBufPtr));
  1620. }
  1621.  
  1622. ReturnStatus
  1623. MachUNIXDup(oldStreamID)
  1624.     int oldStreamID;
  1625. {
  1626.     ReturnStatus    status;
  1627.     Address        usp;
  1628.     int            dummy;
  1629.  
  1630.     usp = (Address) (machCurStatePtr->userState.regState.regs[SP] - 4);
  1631.     dummy = FS_ANYID;
  1632.     status = Vm_CopyOut(sizeof(int), (Address)&dummy, usp);
  1633.     if (status != SUCCESS) {
  1634.     return(status);
  1635.     }
  1636.     status = Fs_GetNewIDStub(oldStreamID, (int *)usp);
  1637.     if (status == SUCCESS) {
  1638.     (void)Vm_CopyIn(sizeof(int), usp, 
  1639.             (Address)&machCurStatePtr->userState.unixRetVal);
  1640.     }
  1641.     return(status);
  1642. }
  1643.  
  1644. ReturnStatus
  1645. MachUNIXDup2(oldStreamID, newStreamID)
  1646.     int oldStreamID;        /* original stream identifier */
  1647.     int newStreamID;        /* new stream identifier */
  1648. {
  1649.     ReturnStatus    status;
  1650.     Address        usp;
  1651.  
  1652.     usp = (Address) (machCurStatePtr->userState.regState.regs[SP] - 4);
  1653.     status = Vm_CopyOut(sizeof(int), (Address)&newStreamID, usp);
  1654.     if (status != SUCCESS) {
  1655.     return(status);
  1656.     }
  1657.     status = Fs_GetNewIDStub(oldStreamID, (int *)usp);
  1658.     if (status == SUCCESS) {
  1659.     (void)Vm_CopyIn(sizeof(int), usp, 
  1660.             (Address)&machCurStatePtr->userState.unixRetVal);
  1661.     }
  1662.     return(status);
  1663. }
  1664.  
  1665. ReturnStatus
  1666. MachUNIXPipe(filedes)
  1667.     int    filedes[2];
  1668. {
  1669.     ReturnStatus    status;
  1670.  
  1671.     status = Fs_CreatePipeStub(&(filedes[0]), &(filedes[1]));
  1672.     if (status == SUCCESS) {
  1673.     /*
  1674.      * When pipe returns, the stub expects v0 to contain the first
  1675.      * file id and v1 to contain the second one.  Our caller will
  1676.      * put unixRetVal into v0 for us, but we have to deal with v1.
  1677.      */
  1678.     (void)Vm_CopyIn(sizeof(int), (Address)&(filedes[0]),
  1679.             (Address)&machCurStatePtr->userState.unixRetVal);
  1680.     (void)Vm_CopyIn(sizeof(int), (Address)&(filedes[1]),
  1681.             (Address)&machCurStatePtr->userState.regState.regs[V1]);
  1682.     }
  1683. }
  1684.  
  1685. ReturnStatus
  1686. MachUNIXGetGID()
  1687. {
  1688.     /*
  1689.      * The Sprite group id for Sprite at Berkeley.  Should do a better job
  1690.      * of this.
  1691.      */
  1692.     machCurStatePtr->userState.unixRetVal = 155;
  1693.  
  1694.     return(SUCCESS);
  1695. }
  1696.  
  1697. ReturnStatus
  1698. MachUNIXSymlink(target, link) 
  1699.     char *target;
  1700.     char *link;
  1701. {
  1702.     return(Fs_SymLinkStub(target, link, FALSE));
  1703. }
  1704.  
  1705. ReturnStatus
  1706. MachUNIXReadLink(link, buffer, numBytes)
  1707.     char *link;            /* name of link file to read */
  1708.     char *buffer;        /* pointer to buffer area */
  1709.     int numBytes;        /* number of bytes to read */
  1710. {
  1711.     ReturnStatus status;    /* result returned by Fs_Read */
  1712.     Address     usp;
  1713.  
  1714.     usp = (Address) (machCurStatePtr->userState.regState.regs[SP] - 4);
  1715.  
  1716.     status = Fs_ReadLinkStub(link, numBytes, buffer, (int *)usp);
  1717.     if (status == SUCCESS) {
  1718.     (void)Vm_CopyIn(sizeof(int), usp, 
  1719.             (Address)&machCurStatePtr->userState.unixRetVal);
  1720.     /*
  1721.      * Sprite's Fs_ReadLink includes the terminating null character
  1722.      * in the character count return  while Unix doesn't. 
  1723.      */
  1724.     machCurStatePtr->userState.unixRetVal -= 1;
  1725.     }
  1726.     return(status);
  1727. }
  1728.  
  1729. #define PERMISSION_MASK 0777
  1730.  
  1731. ReturnStatus
  1732. MachUNIXUmask(newMask)
  1733.     int newMask;
  1734. {
  1735.     ReturnStatus status;    /* result returned by Fs_Read */
  1736.     Address        usp;
  1737.  
  1738.     usp = (Address) (machCurStatePtr->userState.regState.regs[SP] - 4);
  1739.  
  1740.     status = Fs_SetDefPermStub((~newMask) & PERMISSION_MASK, (int *)usp);
  1741.     if (status == SUCCESS) {
  1742.     (void)Vm_CopyIn(sizeof(int), usp, 
  1743.             (Address)&machCurStatePtr->userState.unixRetVal);
  1744.     machCurStatePtr->userState.unixRetVal = 
  1745.         (~(machCurStatePtr->userState.unixRetVal)) & PERMISSION_MASK;
  1746.     }
  1747.     return(status);
  1748. }
  1749.  
  1750. ReturnStatus
  1751. MachUNIXGetPageSize()
  1752. {
  1753.     machCurStatePtr->userState.unixRetVal = vm_PageSize;
  1754.     return(SUCCESS);
  1755. }
  1756.  
  1757. ReturnStatus
  1758. MachUNIXGetGroups(gidsetlen, gidset)
  1759.     int gidsetlen;
  1760.     int *gidset;
  1761. {
  1762.     ReturnStatus status;    /* result returned by Proc_GetGroupIDs */
  1763.     Address usp;
  1764.  
  1765.     usp = (Address) (machCurStatePtr->userState.regState.regs[SP] - 4);
  1766.  
  1767.     status = Proc_GetGroupIDs(gidsetlen, gidset, (int *)usp);
  1768.     if (status == SUCCESS) {
  1769.     (void)Vm_CopyIn(sizeof(int), usp, 
  1770.             (Address)&machCurStatePtr->userState.unixRetVal);
  1771.     if (machCurStatePtr->userState.unixRetVal > gidsetlen) {
  1772.         machCurStatePtr->userState.unixRetVal = gidsetlen;
  1773.     }
  1774.     }
  1775.     return(status);
  1776. }
  1777.  
  1778. ReturnStatus
  1779. MachUNIXSetGroups(ngroups, gidset)
  1780.     int ngroups;
  1781.     int *gidset;
  1782. {
  1783.     return(Proc_SetGroupIDs(ngroups, gidset));
  1784. }
  1785.  
  1786. ReturnStatus
  1787. MachUNIXGetPGrp(pid)
  1788.     int pid;
  1789. {
  1790.     Address usp;
  1791.     ReturnStatus status;    /* result returned by Proc_GetFamilyID */
  1792.  
  1793.     usp = (Address) (machCurStatePtr->userState.regState.regs[SP] - 4);
  1794.     if (pid == 0) {
  1795.     pid = PROC_MY_PID;
  1796.     }
  1797.     status = Proc_GetFamilyID(pid, (int *)usp);
  1798.     if (status == SUCCESS) {
  1799.     (void)Vm_CopyIn(sizeof(int), usp, 
  1800.                 (Address)&machCurStatePtr->userState.unixRetVal);
  1801.     }
  1802.     return(status);
  1803. }
  1804.  
  1805. ReturnStatus MachUNIXSetPGrp(pid, pgrp)
  1806.     int pid;
  1807. {
  1808.     if (pid == 0) {
  1809.     pid = PROC_MY_PID;
  1810.     }
  1811.     return(Proc_SetFamilyID(pid, pgrp));
  1812. }
  1813.  
  1814. ReturnStatus MachUNIXWait(statusPtr, options, unixRusagePtr)
  1815.     union    wait    *statusPtr;
  1816.     int            options;
  1817.     struct    rusage    *unixRusagePtr;
  1818. {
  1819.     Proc_ResUsage spriteRusage;
  1820.     Proc_ResUsage *spriteRusagePtr;
  1821.     ReturnStatus status;    /* result returned by Proc_Wait */
  1822.     int pid;            /* process ID of child */
  1823.     int *pidPtr;
  1824.     int reason;            /* reason child exited */
  1825.     int *reasonPtr;
  1826.     int childStatus;        /* ReturnStatus of child */
  1827.     int *childStatusPtr;
  1828.     int    flags = 0;
  1829.     Address usp;
  1830.     union wait waitStatus;
  1831.     struct    rusage    unixRusage;
  1832.  
  1833.     if (!(options & WNOHANG)) {
  1834.     flags |= PROC_WAIT_BLOCK;
  1835.     }
  1836.     if (options & WUNTRACED) {
  1837.     flags |= PROC_WAIT_FOR_SUSPEND;
  1838.     }
  1839.  
  1840.     usp = (Address)(machCurStatePtr->userState.regState.regs[SP]);
  1841.     pidPtr = (int *)(usp - 4);
  1842.     reasonPtr = (int *)(usp - 8);
  1843.     childStatusPtr = (int *)(usp - 12);
  1844.     spriteRusagePtr = (Proc_ResUsage *)(usp - 12 - sizeof(Proc_ResUsage));
  1845.     status = Proc_Wait(0, (int *) NULL, flags, pidPtr, reasonPtr, 
  1846.                childStatusPtr, (int *)NULL, spriteRusagePtr);
  1847.     if (status == GEN_ABORTED_BY_SIGNAL) {
  1848.     printf("Wait blown away by signal\n");
  1849.     }
  1850.     if (status != SUCCESS) {
  1851.     return(status);
  1852.     }
  1853.     (void)Vm_CopyIn(sizeof(int), (Address)pidPtr, (Address)&pid);
  1854.     (void)Vm_CopyIn(sizeof(int), (Address)reasonPtr, (Address)&reason);
  1855.     (void)Vm_CopyIn(sizeof(int), (Address)childStatusPtr,
  1856.            (Address)&childStatus);
  1857.     (void)Vm_CopyIn(sizeof(int), (Address)spriteRusagePtr,
  1858.            (Address)&spriteRusage);
  1859.     if (statusPtr != NULL)  {
  1860.     int    unixSignal;
  1861.     waitStatus.w_status = 0;
  1862.     if (reason == PROC_TERM_SUSPENDED) {
  1863.         (void)Compat_SpriteSignalToUnix(childStatus, &unixSignal);
  1864.         waitStatus.w_stopval = WSTOPPED;
  1865.         waitStatus.w_stopsig = unixSignal;
  1866.     } else if (reason == PROC_TERM_SIGNALED ||
  1867.            reason == PROC_TERM_RESUMED) {
  1868.         (void)Compat_SpriteSignalToUnix(childStatus, &unixSignal);
  1869.         waitStatus.w_termsig = unixSignal;
  1870.         /* NEED TO HANDLE coredump FIELD */
  1871.     } else {
  1872.         waitStatus.w_retcode = childStatus;
  1873.     }
  1874.     status = Vm_CopyOut(sizeof(waitStatus), (Address)&waitStatus,
  1875.                 (Address)statusPtr);
  1876.     if (status != SUCCESS) {
  1877.         return(status);
  1878.     }
  1879.     }
  1880.     if (unixRusagePtr != NULL) {
  1881.     /*
  1882.      * Return the total time used by the process and all its children.
  1883.      */
  1884.     Time totalKTime;
  1885.     Time totalUTime;
  1886.  
  1887.     bzero((char *) &unixRusage, sizeof(*unixRusagePtr));
  1888.     Time_Add(spriteRusage.userCpuUsage, spriteRusage.childUserCpuUsage,
  1889.                         &totalUTime);
  1890.     Time_Add(spriteRusage.kernelCpuUsage,
  1891.          spriteRusage.childKernelCpuUsage, &totalKTime);
  1892.     unixRusage.ru_utime.tv_sec = totalUTime.seconds;
  1893.     unixRusage.ru_utime.tv_usec = totalUTime.microseconds;
  1894.     unixRusage.ru_stime.tv_sec = totalKTime.seconds;
  1895.     unixRusage.ru_stime.tv_usec = totalKTime.microseconds;
  1896.     unixRusage.ru_nvcsw = spriteRusage.numWaitEvents;
  1897.     unixRusage.ru_nivcsw = spriteRusage.numQuantumEnds;
  1898.     status = Vm_CopyOut(sizeof(unixRusage), (Address)&unixRusage,
  1899.                 (Address)unixRusagePtr);
  1900.     if (status != SUCCESS) {
  1901.         return(status);
  1902.     }
  1903.     }
  1904.     machCurStatePtr->userState.unixRetVal = pid;
  1905.     return(SUCCESS);
  1906. }
  1907.  
  1908. ReturnStatus
  1909. MachUNIXGetDTableSize()
  1910. {
  1911.     machCurStatePtr->userState.unixRetVal = 100;
  1912.     return(SUCCESS);
  1913. }
  1914.  
  1915. ReturnStatus
  1916. MachUNIXSelect(width, readfds, writefds, exceptfds, timeout)
  1917.     int width, *readfds, *writefds, *exceptfds;
  1918.     Time *timeout;
  1919. {
  1920.     Address        usp;
  1921.     ReturnStatus    status;
  1922.  
  1923.     usp = (Address)(machCurStatePtr->userState.regState.regs[SP] - 4);
  1924.     status = Fs_SelectStub(width, timeout, readfds, writefds,
  1925.                exceptfds, (int *)usp);
  1926.     if (status == SUCCESS) {
  1927.     (void)Vm_CopyIn(sizeof(int), usp, 
  1928.             (Address)&machCurStatePtr->userState.unixRetVal);
  1929.     } else if (status == FS_TIMEOUT) {
  1930.     int bytesInMask;
  1931.     int *zeroPtr;
  1932.  
  1933.     bytesInMask = ((width + 31) / 32) * sizeof(int);
  1934.     zeroPtr = (int *)malloc(bytesInMask);
  1935.     bzero((Address)zeroPtr, bytesInMask);
  1936.  
  1937.     if (readfds != NULL) {
  1938.         (void)Vm_CopyOut(bytesInMask, (Address)zeroPtr, 
  1939.                  (Address)readfds);
  1940.     }
  1941.     if (writefds != NULL) {
  1942.         (void)Vm_CopyOut(bytesInMask, (Address)zeroPtr, 
  1943.                  (Address)writefds);
  1944.     }
  1945.     if (exceptfds != NULL) {
  1946.         (void)Vm_CopyOut(bytesInMask, (Address)zeroPtr, 
  1947.                  (Address)exceptfds);
  1948.     }
  1949.     free((Address)zeroPtr);
  1950.         status = SUCCESS;
  1951.     }
  1952.     return(status);
  1953. }
  1954.  
  1955. ReturnStatus
  1956. MachUNIXFSync(fd)
  1957.     int fd;
  1958. {
  1959.     return(Fs_FileWriteBackStub(fd, -1, -1, 1));
  1960. }
  1961.  
  1962. /*ARGSUSED*/
  1963. ReturnStatus
  1964. MachUNIXSetPriority(which, who, prio)
  1965.     int which, who, prio;
  1966. {
  1967.     return(SUCCESS);
  1968. }
  1969.  
  1970. /*ARGSUSED*/
  1971. ReturnStatus
  1972. MachUNIXGetPriority(which, who, prio)
  1973.     int which, who, prio;
  1974. {
  1975.     machCurStatePtr->userState.unixRetVal = 0;
  1976.     return(SUCCESS);
  1977. }
  1978.  
  1979. ReturnStatus
  1980. MachUNIXGetTimeOfDay(tp, tzpPtr)
  1981.     struct timeval     *tp;
  1982.     struct timezone     *tzpPtr;
  1983. {
  1984.     struct timezone    tzp;
  1985.     int            localOffset;
  1986.     Boolean        DST;    
  1987.     ReturnStatus    status;
  1988.     Time        curTime;
  1989.  
  1990.     Timer_GetRealTimeOfDay(&curTime, &localOffset, &DST);
  1991.  
  1992.     status = Vm_CopyOut(sizeof(Time), (Address)&curTime, (Address)tp);
  1993.     if (status != SUCCESS) {
  1994.     return(status);
  1995.     }
  1996.  
  1997.     if (tzpPtr != (struct timezone *) NULL) {
  1998.     tzp.tz_minuteswest     = -localOffset;
  1999.     tzp.tz_dsttime         = DST;
  2000.     return(Vm_CopyOut(sizeof(struct timezone), (Address)&tzp,
  2001.               (Address)tzpPtr));
  2002.     } else {
  2003.     return(SUCCESS);
  2004.     }
  2005. }
  2006.  
  2007.  
  2008.  
  2009. ReturnStatus
  2010. MachUNIXSetTimeOfDay(tp, tzpPtr)
  2011.     struct timeval *tp;
  2012.     struct timezone *tzpPtr;
  2013. {
  2014.     ReturnStatus status;    /* result returned by Sys_SetTimeOfDay */
  2015.     Time curTime;
  2016.     struct timezone tzp;
  2017.  
  2018.  
  2019.     /*
  2020.      * Unix negates the local offset from UTC to make it positive
  2021.      * for locations west of the prime meridian. 
  2022.      */
  2023.  
  2024.     if (tzpPtr == NULL) {
  2025.     int localOffset;
  2026.     Boolean DST;
  2027.  
  2028.     Timer_GetRealTimeOfDay(&curTime, &localOffset, &DST);
  2029.     status = Vm_CopyIn(sizeof(Time), (Address)tp, (Address)&curTime);
  2030.     if (status != SUCCESS) {
  2031.         return(status);
  2032.     }
  2033.     Timer_SetTimeOfDay(curTime, localOffset, DST);
  2034.     } else if (tp == NULL) {
  2035.     Timer_GetRealTimeOfDay(&curTime, (int *) NULL, (Boolean *) NULL);
  2036.     status = Vm_CopyIn(sizeof(tzp), (Address)tzpPtr, (Address)&tzp);
  2037.     if (status != SUCCESS) {
  2038.         return(status);
  2039.     }
  2040.     Timer_SetTimeOfDay(curTime, -(tzp.tz_minuteswest), tzp.tz_dsttime);
  2041.     } else {
  2042.     status = Vm_CopyIn(sizeof(Time), (Address)tp, (Address)&curTime);
  2043.     if (status != SUCCESS) {
  2044.         return(status);
  2045.     }
  2046.     status = Vm_CopyIn(sizeof(tzp), (Address)tzpPtr, (Address)&tzp);
  2047.     if (status != SUCCESS) {
  2048.         return(status);
  2049.     }
  2050.     Timer_SetTimeOfDay(curTime, -(tzp.tz_minuteswest), tzp.tz_dsttime);
  2051.     }
  2052.     return(SUCCESS);
  2053. }
  2054.  
  2055. /*ARGSUSED*/
  2056. ReturnStatus
  2057. MachUNIXGetDirEntries(fd, buf, nbytes, basep)
  2058.     int  fd;
  2059.     char *buf;
  2060.     int nbytes;
  2061.     long *basep;
  2062. {
  2063.     ReturnStatus status;    /* result returned by Fs_Read */
  2064.     Address    usp;
  2065.     int        bytesAcc;
  2066.     Fslcl_DirEntry    *dirPtr;
  2067.     Address    addr;
  2068.     int        i;
  2069.  
  2070.     usp = (Address)(machCurStatePtr->userState.regState.regs[SP] - 4);
  2071.     status = Fs_ReadStub(fd, nbytes, buf, (int *)usp);
  2072.     if (status == SUCCESS) {
  2073.     (void)Vm_CopyIn(sizeof(int), usp,
  2074.                 (Address)&machCurStatePtr->userState.unixRetVal);
  2075.     if (machCurStatePtr->userState.unixRetVal == 0) {
  2076.         return(SUCCESS);
  2077.     }
  2078.     } else {
  2079.     return(status);
  2080.     }
  2081.     Vm_MakeAccessible(VM_OVERWRITE_ACCESS, 
  2082.         machCurStatePtr->userState.unixRetVal, buf, &bytesAcc, &addr);
  2083.     if (bytesAcc != machCurStatePtr->userState.unixRetVal) {
  2084.     panic("User buffer not accessible, but we just wrote to it !!!\n");
  2085.     }
  2086.     /*
  2087.      * Check against big-endian/little-endian conflict.
  2088.      * The max record length is 512, which is 02 when byteswapped.
  2089.      * The min record length is 8, which is > 512 when byteswapped.
  2090.      * All other values fall outside the range 8-512 when byteswapped.
  2091.      */
  2092.     dirPtr = (Fslcl_DirEntry *)addr;
  2093.     if (dirPtr->recordLength > FSLCL_DIR_BLOCK_SIZE ||
  2094.     dirPtr->recordLength < 2 * sizeof(int)) {
  2095.     i = bytesAcc;
  2096.     while (i > 0) {
  2097.         union {
  2098.         short    s;
  2099.         char    c[2];
  2100.         } shortIn, shortOut;
  2101.         union {
  2102.         int    i;
  2103.         char    c[4];
  2104.         } intIn, intOut;
  2105.  
  2106.         if (dirPtr->nameLength <= FS_MAX_NAME_LENGTH) {
  2107.         printf("MachUNIXGetDirEntries: Bad directory format\n");
  2108.         }
  2109.         intIn.i = dirPtr->fileNumber;
  2110.         intOut.c[0] = intIn.c[3];
  2111.         intOut.c[1] = intIn.c[2];
  2112.         intOut.c[2] = intIn.c[1];
  2113.         intOut.c[3] = intIn.c[0];
  2114.         dirPtr->fileNumber = intOut.i;
  2115.  
  2116.         shortIn.s = dirPtr->recordLength;
  2117.         shortOut.c[0] = shortIn.c[1];
  2118.         shortOut.c[1] = shortIn.c[0];
  2119.         dirPtr->recordLength = shortOut.s;
  2120.  
  2121.         shortIn.s = dirPtr->nameLength;
  2122.         shortOut.c[0] = shortIn.c[1];
  2123.         shortOut.c[1] = shortIn.c[0];
  2124.         dirPtr->nameLength = shortOut.s;
  2125.  
  2126.         i -= dirPtr->recordLength;
  2127.         dirPtr = (Fslcl_DirEntry *) ((Address)dirPtr + dirPtr->recordLength);
  2128.     }
  2129.     }
  2130.     Vm_MakeUnaccessible(addr, bytesAcc);
  2131.     return(SUCCESS);
  2132. }
  2133.  
  2134. #define COPYTIME(TO,FROM) { \
  2135.         (TO).tv_sec = (FROM).seconds; \
  2136.         (TO).tv_usec = (FROM).microseconds; \
  2137.       }
  2138.  
  2139. ReturnStatus
  2140. MachUNIXGetRUsage(who, rusage)
  2141.      int who;
  2142.      struct rusage *rusage;
  2143. {
  2144.     ReturnStatus status;        /* result returned by Proc_GetResUsage */
  2145.     Proc_ResUsage spriteUsage;         /* sprite resource usage buffer */
  2146.     struct rusage unixUsage;
  2147.  
  2148.     Address    usp;
  2149.  
  2150.     usp = (Address)(machCurStatePtr->userState.regState.regs[SP] - 
  2151.             sizeof(Proc_ResUsage));
  2152.     status = Proc_GetResUsage(PROC_MY_PID, (Proc_ResUsage *)usp);
  2153.     if (status != SUCCESS) {
  2154.     return(status);
  2155.     } else {
  2156.     (void)Vm_CopyIn(sizeof(Proc_ResUsage), usp, (Address)&spriteUsage);
  2157.     if (who == RUSAGE_SELF) {
  2158.         COPYTIME(unixUsage.ru_utime, spriteUsage.userCpuUsage);
  2159.         COPYTIME(unixUsage.ru_stime, spriteUsage.kernelCpuUsage);
  2160.     } else {
  2161.         COPYTIME(unixUsage.ru_utime, spriteUsage.childUserCpuUsage);
  2162.         COPYTIME(unixUsage.ru_stime, spriteUsage.childKernelCpuUsage);
  2163.     }
  2164.     unixUsage.ru_maxrss = 0;
  2165.     unixUsage.ru_ixrss = 0;    /* integral shared memory size */
  2166.     unixUsage.ru_idrss = 0;    /* integral unshared data size */
  2167.     unixUsage.ru_isrss = 0;    /* integral unshared stack size */
  2168.     unixUsage.ru_minflt = 0;    /* page reclaims */
  2169.     unixUsage.ru_majflt = 0;    /* page faults */
  2170.     unixUsage.ru_nswap = 0;    /* swaps */
  2171.     unixUsage.ru_inblock = 0;    /* block input operations */
  2172.     unixUsage.ru_oublock = 0;    /* block output operations */
  2173.     unixUsage.ru_msgsnd = 0;    /* messages sent */
  2174.     unixUsage.ru_msgrcv = 0;    /* messages received */
  2175.     unixUsage.ru_nsignals = 0;    /* signals received */
  2176.     unixUsage.ru_nvcsw =
  2177.             spriteUsage.numWaitEvents;  /* voluntary context switches */
  2178.     unixUsage.ru_nivcsw =
  2179.             spriteUsage.numQuantumEnds;  /* involuntary context switches */
  2180.  
  2181.     return(Vm_CopyOut(sizeof(unixUsage), (Address)&unixUsage, 
  2182.               (Address)rusage));
  2183.     }
  2184. }
  2185.  
  2186. ReturnStatus
  2187. MachUNIXReadv(stream, iov, iovcnt)
  2188.     int stream;            /* descriptor for stream to read. */
  2189.     register struct iovec *iov;    /* pointer to array of iovecs. */
  2190.     int iovcnt;            /* number of  iovecs in iov. */
  2191. {
  2192.     ReturnStatus status;    /* result returned by Fs_Read */
  2193.     int amountRead;        /* place to hold number of bytes read */
  2194.     int totalRead = 0;        /* place to hold total # of bytes read */
  2195.     int i;
  2196.     Address    usp;
  2197.  
  2198.     usp = (Address)(machCurStatePtr->userState.regState.regs[SP] - 4);
  2199.  
  2200.     for (i=0; i < iovcnt; i++, iov++) {
  2201.     status = Fs_ReadStub(stream, iov->iov_len, iov->iov_base, (int *)usp);
  2202.     if (status != SUCCESS) {
  2203.         break;
  2204.     } else {
  2205.         (void)Vm_CopyIn(sizeof(int), usp, (Address)&amountRead);
  2206.         totalRead += amountRead;
  2207.     }
  2208.     }
  2209.  
  2210.     /* 
  2211.      * If we get an error after reading in something, that still 
  2212.      * counts as success.
  2213.      */
  2214.  
  2215.     if (totalRead > 0) {
  2216.     status = SUCCESS;
  2217.     }
  2218.     if (status == SUCCESS) {
  2219.     machCurStatePtr->userState.unixRetVal = totalRead;
  2220.     }
  2221.     return(status);
  2222. }
  2223.  
  2224. ReturnStatus
  2225. MachUNIXWritev(stream, iov, iovcnt)
  2226.     int stream;            /* descriptor for stream to read. */
  2227.     register struct iovec *iov;    /* pointer to array of iovecs. */
  2228.     int iovcnt;            /* number of  iovecs in iov. */
  2229. {
  2230.     ReturnStatus status;    /* result returned by Fs_Read */
  2231.     int amountWritten;        /* place to hold number of bytes read */
  2232.     int totalWritten = 0;    /* place to hold total # of bytes written */
  2233.     int i;
  2234.     Address    usp;
  2235.  
  2236.     usp = (Address)(machCurStatePtr->userState.regState.regs[SP] - 4);
  2237.  
  2238.     for (i=0; i < iovcnt; i++, iov++) {
  2239.     status = Fs_WriteStub(stream, iov->iov_len, iov->iov_base, (int *)usp);
  2240.     if (status != SUCCESS) {
  2241.         break;
  2242.     } else {
  2243.         (void)Vm_CopyIn(sizeof(int), usp, (Address)&amountWritten);
  2244.         totalWritten += amountWritten;
  2245.     }
  2246.     }
  2247.  
  2248.     /* 
  2249.      * If we get an error after writing out something, that still 
  2250.      * counts as success.
  2251.      */
  2252.  
  2253.     if (totalWritten > 0) {
  2254.     status = SUCCESS;
  2255.     }
  2256.     if (status == SUCCESS) {
  2257.     machCurStatePtr->userState.unixRetVal = totalWritten;
  2258.     }
  2259.     return(status);
  2260. }
  2261.  
  2262. ReturnStatus
  2263. MachUNIXSetREUID(ruid, euid)
  2264.     int    ruid, euid;
  2265. {
  2266.     if (ruid == -1) {
  2267.     ruid = PROC_NO_ID;
  2268.     }
  2269.     if (euid == -1) {
  2270.     euid = PROC_NO_ID;
  2271.     }
  2272.     return(Proc_SetIDs(ruid, euid));
  2273. }
  2274.  
  2275. ReturnStatus
  2276. MachUNIXSetREGID(rgid, egid)
  2277.     int    rgid, egid;
  2278. {
  2279.     Address    usp;
  2280.     int        array[2];
  2281.     int        num;
  2282.     ReturnStatus    status;
  2283.  
  2284.     usp = (Address)(machCurStatePtr->userState.regState.regs[SP] - 8);
  2285.     if (rgid != -1) {
  2286.     array[0] = rgid;
  2287.     num = 1;
  2288.     if (egid != rgid && egid != -1) {
  2289.         array[1] = egid;
  2290.         num++;
  2291.     }
  2292.     } else if (egid != -1) {
  2293.     array[0] = egid;
  2294.     num++;
  2295.     }
  2296.     if (num > 0) {
  2297.     status = Vm_CopyOut(2 * sizeof(int), (Address)array, usp);
  2298.     if (status != SUCCESS) {
  2299.         return(status);
  2300.     }
  2301.     return(Proc_SetGroupIDs(num, (int *)usp));
  2302.     }
  2303.     return(SUCCESS);
  2304. }
  2305.  
  2306. ReturnStatus
  2307. MachUNIXRename(from, to)
  2308.     char *from;
  2309.     char *to;
  2310. {
  2311.     return(Fs_RenameStub(from, to));
  2312. }
  2313.  
  2314. ReturnStatus
  2315. MachUNIXTruncate(path, length)
  2316.     char *path;
  2317.     unsigned long length;
  2318. {
  2319.     Address    usp;
  2320.     int        *intPtr;
  2321.     int        streamID;
  2322.     ReturnStatus status;
  2323.  
  2324.     usp = (Address)machCurStatePtr->userState.regState.regs[SP];
  2325.     intPtr = (int *)(usp - 4);
  2326.     status = Fs_OpenStub(path, FS_WRITE, 0, intPtr);
  2327.     if (status != SUCCESS) {
  2328.     return(status);
  2329.     }
  2330.     (void)Vm_CopyIn(sizeof(streamID), (Address)intPtr, (Address)&streamID);
  2331.     (void)Vm_CopyOut(sizeof(int), (Address)&length, (Address)intPtr);
  2332.     status = Fs_IOControlStub(streamID, IOC_TRUNCATE, sizeof(int),
  2333.                   (Address)intPtr, 0, (Address)NULL);
  2334.     (void)Fs_UserClose(streamID);
  2335.     return(status);
  2336. }
  2337.  
  2338. ReturnStatus
  2339. MachUNIXFTruncate(fd, length)
  2340.     int fd;
  2341.     unsigned long length;
  2342. {
  2343.     Address    usp;
  2344.     ReturnStatus status;
  2345.  
  2346.     usp = (Address)(machCurStatePtr->userState.regState.regs[SP] - 4);
  2347.     status = Vm_CopyOut(sizeof(int), (Address)&length, usp);
  2348.     if (status != SUCCESS) {
  2349.     return(status);
  2350.     }
  2351.     return(Fs_IOControlStub(fd, IOC_TRUNCATE, sizeof(int),
  2352.                 usp, 0, (Address)NULL));
  2353. }
  2354.  
  2355. #ifndef lint
  2356. ReturnStatus
  2357. MachUNIXLongJumpReturn(sigContextPtr)
  2358.     struct sigcontext *sigContextPtr;
  2359. {
  2360.     struct sigcontext    sigContext;
  2361.     Mach_RegState    *regsPtr;
  2362.     int            dummy;
  2363.     ReturnStatus    status;
  2364.  
  2365.     status = Vm_CopyIn(sizeof(struct sigcontext), (Address)sigContextPtr,
  2366.                (Address)&sigContext);
  2367.     if (status != SUCCESS) {
  2368.     return(status);
  2369.     }
  2370.     regsPtr = &machCurStatePtr->userState.regState;
  2371.     regsPtr->pc = (Address)(sigContext.sc_pc - 4);
  2372.     bcopy(sigContext.sc_regs, regsPtr->regs, sizeof(sigContext.sc_regs));
  2373.     regsPtr->mflo = sigContext.sc_mdlo;
  2374.     regsPtr->mfhi = sigContext.sc_mdhi;
  2375.     bcopy(sigContext.sc_fpregs, regsPtr->fpRegs, sizeof(sigContext.sc_fpregs));
  2376.     regsPtr->fpStatusReg = sigContext.sc_fpc_csr;
  2377.     (void) MachUNIXBlock(&dummy, sigContext.sc_mask);
  2378.     return(SUCCESS);
  2379. }
  2380. #endif
  2381.  
  2382. ReturnStatus
  2383. MachUNIXFLock(descriptor, operation)
  2384.     int    descriptor;
  2385.     int operation;
  2386. {
  2387.     ReturnStatus status;
  2388.     int spriteLockOp = 0;
  2389.     Ioc_LockArgs args;
  2390.     Address usp;
  2391.  
  2392.     if (operation & LOCK_EX) {
  2393.     spriteLockOp |= IOC_LOCK_EXCLUSIVE;
  2394.     } else if (operation & LOCK_SH) {
  2395.     spriteLockOp |= IOC_LOCK_SHARED;
  2396.     }
  2397.     if (operation & LOCK_NB) {
  2398.     spriteLockOp |= IOC_LOCK_NO_BLOCK;
  2399.     }
  2400.     args.flags = spriteLockOp;
  2401.     usp = (Address) (machCurStatePtr->userState.regState.regs[SP] - 
  2402.              sizeof(Ioc_LockArgs));
  2403.     status = Vm_CopyOut(sizeof(Ioc_LockArgs), (Address)&args, usp);
  2404.     if (status != SUCCESS) {
  2405.     return(status);
  2406.     }
  2407.     if (operation & LOCK_UN) {
  2408.     return(Fs_IOControlStub(descriptor, IOC_UNLOCK, sizeof(Ioc_LockArgs),
  2409.                 usp, 0, (Address)NULL));
  2410.     } else {
  2411.     return(Fs_IOControlStub(descriptor, IOC_LOCK, sizeof(Ioc_LockArgs),
  2412.                 usp, 0, (Address)NULL));
  2413.     }
  2414. }
  2415.  
  2416. ReturnStatus
  2417. MachUNIXMkDir(pathName, permissions)
  2418.     char *pathName;        /* The name of the directory to create */
  2419.     int permissions;        /* Permission mask to use on creation */
  2420. {
  2421.     return(Fs_MakeDirStub(pathName, permissions));
  2422. }
  2423.  
  2424.  
  2425. ReturnStatus
  2426. MachUNIXRMDir(pathName)
  2427.     char *pathName;        /* The name of the directory to create */
  2428. {
  2429.     return(Fs_RemoveDirStub(pathName));
  2430. }
  2431.  
  2432. ReturnStatus
  2433. MachUNIXUTimes(path, tvp)
  2434.     char    *path;
  2435.     struct timeval tvp[2];
  2436. {
  2437.     Address        usp;
  2438.     ReturnStatus    status;
  2439.     Fs_Attributes attributes;
  2440.  
  2441.     usp = (Address) (machCurStatePtr->userState.regState.regs[SP] - 
  2442.              sizeof(Fs_Attributes));
  2443.     attributes.accessTime.seconds = tvp[0].tv_sec;
  2444.     attributes.accessTime.microseconds = tvp[0].tv_usec;
  2445.     attributes.dataModifyTime.seconds = tvp[1].tv_sec;
  2446.     attributes.dataModifyTime.microseconds = tvp[1].tv_usec;
  2447.     status = Vm_CopyOut(sizeof(Fs_Attributes), (Address)&attributes, usp);
  2448.     if (status != SUCCESS) {
  2449.     return(status);
  2450.     }
  2451.     return(Fs_SetAttrStub(path, FS_ATTRIB_FILE, (Fs_Attributes *)usp,
  2452.               FS_SET_TIMES));
  2453. }
  2454.  
  2455. ReturnStatus
  2456. MachUNIXKillPG(pgrp, sig)
  2457.     int pgrp;
  2458.     int sig;
  2459. {
  2460.     ReturnStatus status;
  2461.     int         spriteSignal;
  2462.  
  2463.     status = Compat_UnixSignalToSprite(sig, &spriteSignal);
  2464.     if (status == FAILURE || (spriteSignal == NULL && sig != 0)) {
  2465.     return(SYS_INVALID_ARG);
  2466.     }
  2467.     return(Sig_UserSend(spriteSignal, pgrp, TRUE));
  2468. }
  2469.  
  2470. ReturnStatus
  2471. MachUNIXGetRLimit()
  2472. {
  2473.     return(SUCCESS);
  2474. }
  2475.  
  2476. ReturnStatus
  2477. MachUNIXSetRLimit()
  2478. {
  2479.     return(SUCCESS);
  2480. }
  2481.  
  2482. #define MAX_HOST_NAME_LEN 255
  2483.  
  2484. char machHostName[MAX_HOST_NAME_LEN + 1];
  2485. int machHostNameLen = 0;
  2486. char machDomainName[MAX_HOST_NAME_LEN + 1];
  2487. int machDomainNameLen = 0;
  2488. int machHostID;
  2489.  
  2490. ReturnStatus
  2491. MachUNIXGetHostName(name, namelen)
  2492.     char *name;
  2493.     int namelen;
  2494. {
  2495.     int copyLen;
  2496.  
  2497.     if (namelen < machHostNameLen + 1) {
  2498.     copyLen = namelen;
  2499.     } else {
  2500.     copyLen = machHostNameLen + 1;
  2501.     }
  2502.     return(Vm_CopyOut(copyLen, machHostName, name));
  2503. }
  2504.  
  2505. ReturnStatus
  2506. MachUNIXSetHostName(name, namelen)
  2507.     char *name;
  2508.     int namelen;
  2509. {
  2510.     ReturnStatus    status;
  2511.  
  2512.     if (namelen > MAX_HOST_NAME_LEN) {
  2513.     return(SYS_INVALID_ARG);
  2514.     }
  2515.     status = Vm_CopyIn(namelen, name, machHostName);
  2516.     if (status != SUCCESS) {
  2517.     machHostNameLen = 0;
  2518.     return(status);
  2519.     }
  2520.     machHostName[namelen] = 0;
  2521.     machHostNameLen = namelen;
  2522.     return(SUCCESS);
  2523. }
  2524.  
  2525. ReturnStatus
  2526. MachUNIXGetHostID()
  2527. {
  2528.     machCurStatePtr->userState.unixRetVal = machHostID;
  2529.     return(SUCCESS);
  2530. }
  2531.  
  2532. ReturnStatus
  2533. MachUNIXSetHostID(hostid)
  2534.     int hostid;
  2535. {
  2536.     machHostID = hostid;
  2537.     return(SUCCESS);
  2538. }
  2539.  
  2540. ReturnStatus
  2541. MachUNIXGetDomainName(name, namelen)
  2542.     char *name;
  2543.     int namelen;
  2544. {
  2545.     int copyLen;
  2546.  
  2547.     if (namelen < machDomainNameLen + 1) {
  2548.     copyLen = namelen;
  2549.     } else {
  2550.     copyLen = machDomainNameLen + 1;
  2551.     }
  2552.     return(Vm_CopyOut(copyLen, machDomainName, name));
  2553. }
  2554.  
  2555. ReturnStatus
  2556. MachUNIXSetDomainName(name, namelen)
  2557.     char *name;
  2558.     int namelen;
  2559. {
  2560.     ReturnStatus    status;
  2561.  
  2562.     if (namelen > MAX_HOST_NAME_LEN) {
  2563.     return(SYS_INVALID_ARG);
  2564.     }
  2565.     status = Vm_CopyIn(namelen, name, machDomainName);
  2566.     if (status != SUCCESS) {
  2567.     machDomainNameLen = 0;
  2568.     return(status);
  2569.     }
  2570.     machDomainName[namelen] = 0;
  2571.     machDomainNameLen = namelen;
  2572.     return(SUCCESS);
  2573. }
  2574.  
  2575. ReturnStatus
  2576. MachUNIXGetItimer(which, value)
  2577.     int which;
  2578.     struct itimerval *value;
  2579. {
  2580.     return(Proc_GetIntervalTimer(which, (Proc_TimerInterval *) value));
  2581. }
  2582.  
  2583. ReturnStatus
  2584. MachUNIXSetITimer(which, value, ovalue)
  2585.     int which;
  2586.     struct itimerval *value;
  2587.     struct itimerval *ovalue;
  2588. {
  2589.     return(Proc_SetIntervalTimer(which, (Proc_TimerInterval *) value,
  2590.                  (Proc_TimerInterval *) ovalue));
  2591. }
  2592.  
  2593. /*ARGSUSED*/
  2594. ReturnStatus
  2595. MachUNIXGetSysInfo(op, buffer, nbytes, start, arg)
  2596.     unsigned  op;
  2597.     char      *buffer;
  2598.     unsigned   nbytes;
  2599.     int       *start;
  2600.     char       *arg;
  2601. {
  2602. #ifdef actually_do_it
  2603.     switch (op) {
  2604.     case GSI_PROG_ENV:
  2605.     case GSI_MAX_UPROCS:
  2606.     case GSI_TTYP:
  2607.     case GSI_NETBLK:
  2608.     case GSI_BOOTDEV:
  2609.     case GSI_UACSYS:
  2610.     case GSI_UACPARNT:
  2611.     case GSI_UACPROC:
  2612.     default:
  2613.     }
  2614. #endif
  2615.     /*
  2616.      * Just return a 0.  This says that the requested information is
  2617.      * not available which is certainly true for the most part.
  2618.      */
  2619.     machCurStatePtr->userState.unixRetVal = 0;
  2620.     return(SUCCESS);
  2621. }
  2622.  
  2623. ReturnStatus
  2624. MachUNIXSemctl(semid, semnum, cmd, arg)
  2625. int semid, semnum, cmd;
  2626. union semun arg;
  2627. {
  2628.     ReturnStatus    status;
  2629.     Address        usp;
  2630.  
  2631.     usp = (Address) (machCurStatePtr->userState.regState.regs[SP] - 4);
  2632.     status = Sync_SemctlStub(semid, semnum, cmd, arg, usp);
  2633.     if (status == SUCCESS) {
  2634.         (void)Vm_CopyIn(sizeof(int), usp,
  2635.                         (Address)&machCurStatePtr->userState.unixRetVal);
  2636.     }
  2637.     return(status);
  2638. }
  2639.  
  2640. ReturnStatus
  2641. MachUNIXSemop(semid, sops, nsops)
  2642. int semid, nsops;
  2643. struct sembuf *sops;
  2644. {
  2645.     ReturnStatus    status;
  2646.     Address        usp;
  2647.  
  2648.     usp = (Address) (machCurStatePtr->userState.regState.regs[SP] - 4);
  2649.     status = Sync_SemopStub(semid, sops, nsops, usp);
  2650.     if (status == SUCCESS) {
  2651.         (void)Vm_CopyIn(sizeof(int), usp,
  2652.                         (Address)&machCurStatePtr->userState.unixRetVal);
  2653.     }
  2654.     return(status);
  2655. }
  2656.  
  2657. ReturnStatus
  2658. MachUNIXSemget(key, nsems, semflg)
  2659. key_t key;
  2660. int nsems, semflg;
  2661. {
  2662.     ReturnStatus    status;
  2663.     Address        usp;
  2664.  
  2665.     usp = (Address) (machCurStatePtr->userState.regState.regs[SP] - 4);
  2666.     status = Sync_SemgetStub(key, nsems, semflg, usp);
  2667.     if (status == SUCCESS) {
  2668.         (void)Vm_CopyIn(sizeof(int), usp,
  2669.                         (Address)&machCurStatePtr->userState.unixRetVal);
  2670.     }
  2671.     return(status);
  2672. }
  2673.  
  2674. ReturnStatus
  2675. MachUNIXMmap(addr, len, prot, share, fd, pos)
  2676. caddr_t    addr;
  2677. int    len, prot, share, fd;
  2678. off_t    pos;
  2679. {
  2680.     ReturnStatus    status;
  2681.     Address        usp;
  2682.  
  2683.     usp = (Address) (machCurStatePtr->userState.regState.regs[SP] - 4);
  2684.     status = Vm_Mmap(addr, len, prot, share, fd, pos, usp);
  2685.     if (status == SUCCESS) {
  2686.         (void)Vm_CopyIn(sizeof(int), usp,
  2687.                         (Address)&machCurStatePtr->userState.unixRetVal);
  2688.     }
  2689.     return(status);
  2690. }
  2691.  
  2692. ReturnStatus
  2693. MachUNIXMunmap(addr, len)
  2694. caddr_t    addr;
  2695. int    len;
  2696. {
  2697.     ReturnStatus    status;
  2698.     Address        usp;
  2699.  
  2700.     usp = (Address) (machCurStatePtr->userState.regState.regs[SP] - 4);
  2701.     status = Vm_Munmap(addr, len, usp);
  2702.     if (status == SUCCESS) {
  2703.         (void)Vm_CopyIn(sizeof(int), usp,
  2704.                         (Address)&machCurStatePtr->userState.unixRetVal);
  2705.     }
  2706.     return(status);
  2707. }
  2708.  
  2709. ReturnStatus
  2710. MachUNIXMincore(addr, len, vec)
  2711. caddr_t    addr;
  2712. int len;
  2713. char vec[];
  2714. {
  2715.     ReturnStatus    status;
  2716.     Address        usp;
  2717.  
  2718.     usp = (Address) (machCurStatePtr->userState.regState.regs[SP] - 4);
  2719.     status = Vm_Mincore(addr, len, vec, usp);
  2720.     if (status == SUCCESS) {
  2721.         (void)Vm_CopyIn(sizeof(int), usp,
  2722.                         (Address)&machCurStatePtr->userState.unixRetVal);
  2723.     }
  2724.     return(status);
  2725. }
  2726.  
  2727. /************************ Begin Unimplemented calls **********************/
  2728.  
  2729. /*ARGSUSED*/
  2730. ReturnStatus
  2731. MachUNIXSocketPair(d, type, protocol, sv)
  2732.     int d, type, protocol;
  2733.     int sv[2];
  2734. {
  2735.     printf("socketpair is not implemented\n");
  2736.     return(FAILURE);
  2737. }
  2738.  
  2739. /*ARGSUSED*/
  2740. ReturnStatus
  2741. MachUNIXReboot(howto)
  2742.     int howto;
  2743. {
  2744.     printf("reboot is not implemented\n");
  2745.     return(FAILURE);
  2746. }
  2747.  
  2748. ReturnStatus
  2749. MachUNIXSync()
  2750. {
  2751.     printf("sync is not implemented\n");
  2752.     return(FAILURE);
  2753. }
  2754.  
  2755. /*ARGSUSED*/
  2756. ReturnStatus
  2757. MachUNIXPtrace(request, pid, addr, data)
  2758.     int request, pid, *addr, data;
  2759. {
  2760.     printf("ptrace is not implemented\n");
  2761.     return(FAILURE);
  2762. }
  2763.  
  2764. ReturnStatus
  2765. MachUNIXGetDOpt()
  2766. {
  2767.     printf("getdopt is not implemented\n");
  2768.     return(FAILURE);
  2769. }
  2770.  
  2771. ReturnStatus
  2772. MachUNIXSetDOpt()
  2773. {
  2774.     printf("setdopt is not implemented\n");
  2775.     return(FAILURE);
  2776. }
  2777.  
  2778.  
  2779. /*ARGSUSED*/
  2780. ReturnStatus
  2781. MachUNIXAdjTime(delta, olddelta)
  2782.     struct timeval    *delta;
  2783.     struct timeval    *olddelta;
  2784. {
  2785.     printf("adjtime is not implemented\n");
  2786.     return(FAILURE);
  2787. }
  2788.  
  2789. ReturnStatus
  2790. MachUNIXError()
  2791. {
  2792.     printf("MachUNIXError: %s is not implemented\n", 
  2793.         machUNIXSysCallTable[machCurStatePtr->userState.regState.regs[V0]].name);
  2794.     return(FAILURE);
  2795. }
  2796.  
  2797. ReturnStatus
  2798. MachUNIXProfil(buffer, bufsize, offset, scale)
  2799.     char *buffer;
  2800.     int bufsize;
  2801.     int offset;
  2802.     int scale;
  2803. {
  2804.  
  2805.     Prof_Profil(buffer, bufsize, offset, scale);
  2806.     return SUCCESS;
  2807. }
  2808.  
  2809.